Coverage Report

Created: 2025-05-07 19:52

/src/libxml2/xmlschemas.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * schemas.c : implementation of the XML Schema handling and
3
 *             schema validity checking
4
 *
5
 * See Copyright for the status of this software.
6
 *
7
 * Daniel Veillard <veillard@redhat.com>
8
 */
9
10
/*
11
 * TODO:
12
 *   - when types are redefined in includes, check that all
13
 *     types in the redef list are equal
14
 *     -> need a type equality operation.
15
 *   - if we don't intend to use the schema for schemas, we
16
 *     need to validate all schema attributes (ref, type, name)
17
 *     against their types.
18
 *   - Eliminate item creation for: ??
19
 *
20
 * URGENT TODO:
21
 *   - For xsi-driven schema acquisition, augment the IDCs after every
22
 *     acquisition episode (xmlSchemaAugmentIDC).
23
 *
24
 * NOTES:
25
 *   - Eliminated item creation for: <restriction>, <extension>,
26
 *     <simpleContent>, <complexContent>, <list>, <union>
27
 *
28
 * PROBLEMS:
29
 *   - http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0337.html
30
 *     IDC XPath expression and chameleon includes: the targetNamespace is changed, so
31
 *     XPath will have trouble to resolve to this namespace, since not known.
32
 *
33
 *
34
 * CONSTRAINTS:
35
 *
36
 * Schema Component Constraint:
37
 *   All Group Limited (cos-all-limited)
38
 *   Status: complete
39
 *   (1.2)
40
 *     In xmlSchemaGroupDefReferenceTermFixup() and
41
 *   (2)
42
 *     In xmlSchemaParseModelGroup()
43
 *     TODO: Actually this should go to component-level checks,
44
 *     but is done here due to performance. Move it to an other layer
45
 *     is schema construction via an API is implemented.
46
 */
47
48
/* To avoid EBCDIC trouble when parsing on zOS */
49
#if defined(__MVS__)
50
#pragma convert("ISO8859-1")
51
#endif
52
53
#define IN_LIBXML
54
#include "libxml.h"
55
56
#ifdef LIBXML_SCHEMAS_ENABLED
57
58
#include <string.h>
59
#include <libxml/xmlmemory.h>
60
#include <libxml/parser.h>
61
#include <libxml/parserInternals.h>
62
#include <libxml/hash.h>
63
#include <libxml/uri.h>
64
#include <libxml/xmlschemas.h>
65
#include <libxml/schemasInternals.h>
66
#include <libxml/xmlschemastypes.h>
67
#include <libxml/xmlautomata.h>
68
#include <libxml/xmlregexp.h>
69
#include <libxml/dict.h>
70
#include <libxml/encoding.h>
71
#include <libxml/xmlIO.h>
72
#ifdef LIBXML_PATTERN_ENABLED
73
#include <libxml/pattern.h>
74
#endif
75
#ifdef LIBXML_READER_ENABLED
76
#include <libxml/xmlreader.h>
77
#endif
78
79
#include "private/error.h"
80
#include "private/memory.h"
81
#include "private/string.h"
82
83
/* #define WXS_ELEM_DECL_CONS_ENABLED */
84
85
/* #define ENABLE_PARTICLE_RESTRICTION 1 */
86
87
#define ENABLE_REDEFINE
88
89
/* #define ENABLE_NAMED_LOCALS */
90
91
/* #define ENABLE_IDC_NODE_TABLES_TEST */
92
93
#define DUMP_CONTENT_MODEL
94
95
#ifdef LIBXML_READER_ENABLED
96
/* #define XML_SCHEMA_READER_ENABLED */
97
#endif
98
99
0
#define UNBOUNDED (1 << 30)
100
101
0
#define XML_SCHEMAS_NO_NAMESPACE (const xmlChar *) "##"
102
103
/*
104
 * The XML Schemas namespaces
105
 */
106
static const xmlChar *xmlSchemaNs = (const xmlChar *)
107
    "http://www.w3.org/2001/XMLSchema";
108
109
static const xmlChar *xmlSchemaInstanceNs = (const xmlChar *)
110
    "http://www.w3.org/2001/XMLSchema-instance";
111
112
static const xmlChar *xmlNamespaceNs = (const xmlChar *)
113
    "http://www.w3.org/2000/xmlns/";
114
115
/*
116
* Come casting macros.
117
*/
118
0
#define ACTXT_CAST (xmlSchemaAbstractCtxtPtr)
119
0
#define PCTXT_CAST (xmlSchemaParserCtxtPtr)
120
#define VCTXT_CAST (xmlSchemaValidCtxtPtr)
121
0
#define WXS_BASIC_CAST (xmlSchemaBasicItemPtr)
122
0
#define WXS_TREE_CAST (xmlSchemaTreeItemPtr)
123
0
#define WXS_PTC_CAST (xmlSchemaParticlePtr)
124
0
#define WXS_TYPE_CAST (xmlSchemaTypePtr)
125
0
#define WXS_ELEM_CAST (xmlSchemaElementPtr)
126
0
#define WXS_ATTR_GROUP_CAST (xmlSchemaAttributeGroupPtr)
127
0
#define WXS_ATTR_CAST (xmlSchemaAttributePtr)
128
0
#define WXS_ATTR_USE_CAST (xmlSchemaAttributeUsePtr)
129
0
#define WXS_ATTR_PROHIB_CAST (xmlSchemaAttributeUseProhibPtr)
130
0
#define WXS_MODEL_GROUPDEF_CAST (xmlSchemaModelGroupDefPtr)
131
0
#define WXS_MODEL_GROUP_CAST (xmlSchemaModelGroupPtr)
132
0
#define WXS_IDC_CAST (xmlSchemaIDCPtr)
133
0
#define WXS_QNAME_CAST (xmlSchemaQNameRefPtr)
134
0
#define WXS_LIST_CAST (xmlSchemaItemListPtr)
135
136
/*
137
* Macros to query common properties of components.
138
*/
139
0
#define WXS_ITEM_NODE(i) xmlSchemaGetComponentNode(WXS_BASIC_CAST (i))
140
141
0
#define WXS_ITEM_TYPE_NAME(i) xmlSchemaGetComponentTypeStr(WXS_BASIC_CAST (i))
142
/*
143
* Macros for element declarations.
144
*/
145
0
#define WXS_ELEM_TYPEDEF(e) (e)->subtypes
146
147
0
#define WXS_SUBST_HEAD(item) (item)->refDecl
148
/*
149
* Macros for attribute declarations.
150
*/
151
0
#define WXS_ATTR_TYPEDEF(a) (a)->subtypes
152
/*
153
* Macros for attribute uses.
154
*/
155
0
#define WXS_ATTRUSE_DECL(au) (WXS_ATTR_USE_CAST (au))->attrDecl
156
157
0
#define WXS_ATTRUSE_TYPEDEF(au) WXS_ATTR_TYPEDEF(WXS_ATTRUSE_DECL( WXS_ATTR_USE_CAST au))
158
159
0
#define WXS_ATTRUSE_DECL_NAME(au) (WXS_ATTRUSE_DECL(au))->name
160
161
0
#define WXS_ATTRUSE_DECL_TNS(au) (WXS_ATTRUSE_DECL(au))->targetNamespace
162
/*
163
* Macros for attribute groups.
164
*/
165
0
#define WXS_ATTR_GROUP_HAS_REFS(ag) ((WXS_ATTR_GROUP_CAST (ag))->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS)
166
0
#define WXS_ATTR_GROUP_EXPANDED(ag) ((WXS_ATTR_GROUP_CAST (ag))->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED)
167
/*
168
* Macros for particles.
169
*/
170
0
#define WXS_PARTICLE(p) WXS_PTC_CAST (p)
171
172
0
#define WXS_PARTICLE_TERM(p) (WXS_PARTICLE(p))->children
173
174
#define WXS_PARTICLE_TERM_AS_ELEM(p) (WXS_ELEM_CAST WXS_PARTICLE_TERM(p))
175
176
#define WXS_PARTICLE_MODEL(p) WXS_MODEL_GROUP_CAST WXS_PARTICLE(p)->children
177
/*
178
* Macros for model groups definitions.
179
*/
180
0
#define WXS_MODELGROUPDEF_MODEL(mgd) (WXS_MODEL_GROUP_CAST (mgd))->children
181
/*
182
* Macros for model groups.
183
*/
184
#define WXS_IS_MODEL_GROUP(i) \
185
0
    (((i)->type == XML_SCHEMA_TYPE_SEQUENCE) || \
186
0
     ((i)->type == XML_SCHEMA_TYPE_CHOICE) || \
187
0
     ((i)->type == XML_SCHEMA_TYPE_ALL))
188
189
0
#define WXS_MODELGROUP_PARTICLE(mg) WXS_PTC_CAST (mg)->children
190
/*
191
* Macros for schema buckets.
192
*/
193
0
#define WXS_IS_BUCKET_INCREDEF(t) (((t) == XML_SCHEMA_SCHEMA_INCLUDE) || \
194
0
    ((t) == XML_SCHEMA_SCHEMA_REDEFINE))
195
196
0
#define WXS_IS_BUCKET_IMPMAIN(t) (((t) == XML_SCHEMA_SCHEMA_MAIN) || \
197
0
    ((t) == XML_SCHEMA_SCHEMA_IMPORT))
198
199
0
#define WXS_IMPBUCKET(b) ((xmlSchemaImportPtr) (b))
200
201
0
#define WXS_INCBUCKET(b) ((xmlSchemaIncludePtr) (b))
202
/*
203
* Macros for complex/simple types.
204
*/
205
#define WXS_IS_ANYTYPE(i) \
206
0
     (( (i)->type == XML_SCHEMA_TYPE_BASIC) && \
207
0
      ( (WXS_TYPE_CAST (i))->builtInType == XML_SCHEMAS_ANYTYPE))
208
209
#define WXS_IS_COMPLEX(i) \
210
0
    (((i)->type == XML_SCHEMA_TYPE_COMPLEX) || \
211
0
     ((i)->builtInType == XML_SCHEMAS_ANYTYPE))
212
213
#define WXS_IS_SIMPLE(item) \
214
0
    ((item->type == XML_SCHEMA_TYPE_SIMPLE) || \
215
0
     ((item->type == XML_SCHEMA_TYPE_BASIC) && \
216
0
      (item->builtInType != XML_SCHEMAS_ANYTYPE)))
217
218
#define WXS_IS_ANY_SIMPLE_TYPE(i) \
219
0
    (((i)->type == XML_SCHEMA_TYPE_BASIC) && \
220
0
      ((i)->builtInType == XML_SCHEMAS_ANYSIMPLETYPE))
221
222
#define WXS_IS_RESTRICTION(t) \
223
0
    ((t)->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION)
224
225
#define WXS_IS_EXTENSION(t) \
226
0
    ((t)->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION)
227
228
#define WXS_IS_TYPE_NOT_FIXED(i) \
229
0
    (((i)->type != XML_SCHEMA_TYPE_BASIC) && \
230
0
     (((i)->flags & XML_SCHEMAS_TYPE_INTERNAL_RESOLVED) == 0))
231
232
#define WXS_IS_TYPE_NOT_FIXED_1(item) \
233
0
    (((item)->type != XML_SCHEMA_TYPE_BASIC) && \
234
0
     (((item)->flags & XML_SCHEMAS_TYPE_FIXUP_1) == 0))
235
236
#define WXS_TYPE_IS_GLOBAL(t) ((t)->flags & XML_SCHEMAS_TYPE_GLOBAL)
237
238
#define WXS_TYPE_IS_LOCAL(t) (((t)->flags & XML_SCHEMAS_TYPE_GLOBAL) == 0)
239
/*
240
* Macros for exclusively for complex types.
241
*/
242
#define WXS_HAS_COMPLEX_CONTENT(item) \
243
    ((item->contentType == XML_SCHEMA_CONTENT_MIXED) || \
244
     (item->contentType == XML_SCHEMA_CONTENT_EMPTY) || \
245
     (item->contentType == XML_SCHEMA_CONTENT_ELEMENTS))
246
247
#define WXS_HAS_SIMPLE_CONTENT(item) \
248
0
    ((item->contentType == XML_SCHEMA_CONTENT_SIMPLE) || \
249
0
     (item->contentType == XML_SCHEMA_CONTENT_BASIC))
250
251
#define WXS_HAS_MIXED_CONTENT(item) \
252
0
    (item->contentType == XML_SCHEMA_CONTENT_MIXED)
253
254
#define WXS_EMPTIABLE(t) \
255
0
    (xmlSchemaIsParticleEmptiable(WXS_PTC_CAST (t)->subtypes))
256
257
0
#define WXS_TYPE_CONTENTTYPE(t) (t)->subtypes
258
259
0
#define WXS_TYPE_PARTICLE(t) WXS_PTC_CAST (t)->subtypes
260
261
0
#define WXS_TYPE_PARTICLE_TERM(t) WXS_PARTICLE_TERM(WXS_TYPE_PARTICLE(t))
262
/*
263
* Macros for exclusively for simple types.
264
*/
265
0
#define WXS_LIST_ITEMTYPE(t) (t)->subtypes
266
267
0
#define WXS_IS_ATOMIC(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_ATOMIC)
268
269
0
#define WXS_IS_LIST(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_LIST)
270
271
0
#define WXS_IS_UNION(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_UNION)
272
/*
273
* Misc parser context macros.
274
*/
275
0
#define WXS_CONSTRUCTOR(ctx) (ctx)->constructor
276
277
0
#define WXS_HAS_BUCKETS(ctx) \
278
0
( (WXS_CONSTRUCTOR((ctx))->buckets != NULL) && \
279
0
(WXS_CONSTRUCTOR((ctx))->buckets->nbItems > 0) )
280
281
0
#define WXS_SUBST_GROUPS(ctx) WXS_CONSTRUCTOR((ctx))->substGroups
282
283
0
#define WXS_BUCKET(ctx) WXS_CONSTRUCTOR((ctx))->bucket
284
285
#define WXS_SCHEMA(ctx) (ctx)->schema
286
287
#define WXS_ADD_LOCAL(ctx, item) \
288
0
    do { \
289
0
        if ((item != NULL) && \
290
0
            (xmlSchemaAddItemSize(&(WXS_BUCKET(ctx)->locals), 10, \
291
0
                                  item) < 0)) { \
292
0
            xmlSchemaPErrMemory(ctx); \
293
0
            xmlFree(item); \
294
0
            item = NULL; \
295
0
        } \
296
0
    } while (0)
297
298
#define WXS_ADD_GLOBAL(ctx, item) \
299
0
    do { \
300
0
        if ((item != NULL) && \
301
0
            (xmlSchemaAddItemSize(&(WXS_BUCKET(ctx)->globals), 5, \
302
0
                                  item) < 0)) { \
303
0
            xmlSchemaPErrMemory(ctx); \
304
0
            xmlFree(item); \
305
0
            item = NULL; \
306
0
        } \
307
0
    } while (0)
308
309
#define WXS_ADD_PENDING(ctx, item) \
310
0
    do { \
311
0
        if ((item != NULL) && \
312
0
            (xmlSchemaAddItemSize(&((ctx)->constructor->pending), 10, \
313
0
                                  item) < 0)) { \
314
0
            xmlSchemaPErrMemory(ctx); \
315
0
        } \
316
0
    } while (0)
317
/*
318
* xmlSchemaItemList macros.
319
*/
320
0
#define WXS_ILIST_IS_EMPTY(l) ((l == NULL) || ((l)->nbItems == 0))
321
/*
322
* Misc macros.
323
*/
324
#define IS_SCHEMA(node, type) \
325
0
   ((node != NULL) && (node->ns != NULL) && \
326
0
    (xmlStrEqual(node->name, (const xmlChar *) type)) && \
327
0
    (xmlStrEqual(node->ns->href, xmlSchemaNs)))
328
329
0
#define FREE_AND_NULL(str) if ((str) != NULL) { xmlFree((xmlChar *) (str)); str = NULL; }
330
331
/*
332
* Since we put the default/fixed values into the dict, we can
333
* use pointer comparison for those values.
334
* REMOVED: (xmlStrEqual((v1), (v2)))
335
*/
336
0
#define WXS_ARE_DEFAULT_STR_EQUAL(v1, v2) ((v1) == (v2))
337
338
0
#define INODE_NILLED(item) (item->flags & XML_SCHEMA_ELEM_INFO_NILLED)
339
340
0
#define CAN_PARSE_SCHEMA(b) (((b)->doc != NULL) && ((b)->parsed == 0))
341
342
0
#define HFAILURE if (res == -1) goto exit_failure;
343
344
0
#define HERROR if (res != 0) goto exit_error;
345
346
0
#define HSTOP(ctx) if ((ctx)->stop) goto exit;
347
/*
348
* Some flags used for various schema constraints.
349
*/
350
0
#define SUBSET_RESTRICTION  1<<0
351
0
#define SUBSET_EXTENSION    1<<1
352
#define SUBSET_SUBSTITUTION 1<<2
353
#define SUBSET_LIST         1<<3
354
#define SUBSET_UNION        1<<4
355
356
typedef struct _xmlSchemaNodeInfo xmlSchemaNodeInfo;
357
typedef xmlSchemaNodeInfo *xmlSchemaNodeInfoPtr;
358
359
typedef struct _xmlSchemaItemList xmlSchemaItemList;
360
typedef xmlSchemaItemList *xmlSchemaItemListPtr;
361
struct _xmlSchemaItemList {
362
    void **items;  /* used for dynamic addition of schemata */
363
    int nbItems; /* used for dynamic addition of schemata */
364
    int sizeItems; /* used for dynamic addition of schemata */
365
};
366
367
0
#define XML_SCHEMA_CTXT_PARSER 1
368
0
#define XML_SCHEMA_CTXT_VALIDATOR 2
369
370
typedef struct _xmlSchemaAbstractCtxt xmlSchemaAbstractCtxt;
371
typedef xmlSchemaAbstractCtxt *xmlSchemaAbstractCtxtPtr;
372
struct _xmlSchemaAbstractCtxt {
373
    int type; /* E.g. XML_SCHEMA_CTXT_VALIDATOR */
374
    void *dummy; /* Fix alignment issues */
375
};
376
377
typedef struct _xmlSchemaBucket xmlSchemaBucket;
378
typedef xmlSchemaBucket *xmlSchemaBucketPtr;
379
380
0
#define XML_SCHEMA_SCHEMA_MAIN 0
381
0
#define XML_SCHEMA_SCHEMA_IMPORT 1
382
0
#define XML_SCHEMA_SCHEMA_INCLUDE 2
383
0
#define XML_SCHEMA_SCHEMA_REDEFINE 3
384
385
/**
386
 * xmlSchemaSchemaRelation:
387
 *
388
 * Used to create a graph of schema relationships.
389
 */
390
typedef struct _xmlSchemaSchemaRelation xmlSchemaSchemaRelation;
391
typedef xmlSchemaSchemaRelation *xmlSchemaSchemaRelationPtr;
392
struct _xmlSchemaSchemaRelation {
393
    xmlSchemaSchemaRelationPtr next;
394
    int type; /* E.g. XML_SCHEMA_SCHEMA_IMPORT */
395
    const xmlChar *importNamespace;
396
    xmlSchemaBucketPtr bucket;
397
};
398
399
0
#define XML_SCHEMA_BUCKET_MARKED 1<<0
400
0
#define XML_SCHEMA_BUCKET_COMPS_ADDED 1<<1
401
402
struct _xmlSchemaBucket {
403
    int type;
404
    int flags;
405
    const xmlChar *schemaLocation;
406
    const xmlChar *origTargetNamespace;
407
    const xmlChar *targetNamespace;
408
    xmlDocPtr doc;
409
    xmlSchemaSchemaRelationPtr relations;
410
    int located;
411
    int parsed;
412
    int imported;
413
    int preserveDoc;
414
    xmlSchemaItemListPtr globals; /* Global components. */
415
    xmlSchemaItemListPtr locals; /* Local components. */
416
};
417
418
/**
419
 * xmlSchemaImport:
420
 * (extends xmlSchemaBucket)
421
 *
422
 * Reflects a schema. Holds some information
423
 * about the schema and its toplevel components. Duplicate
424
 * toplevel components are not checked at this level.
425
 */
426
typedef struct _xmlSchemaImport xmlSchemaImport;
427
typedef xmlSchemaImport *xmlSchemaImportPtr;
428
struct _xmlSchemaImport {
429
    int type; /* Main OR import OR include. */
430
    int flags;
431
    const xmlChar *schemaLocation; /* The URI of the schema document. */
432
    /* For chameleon includes, @origTargetNamespace will be NULL */
433
    const xmlChar *origTargetNamespace;
434
    /*
435
    * For chameleon includes, @targetNamespace will be the
436
    * targetNamespace of the including schema.
437
    */
438
    const xmlChar *targetNamespace;
439
    xmlDocPtr doc; /* The schema node-tree. */
440
    /* @relations will hold any included/imported/redefined schemas. */
441
    xmlSchemaSchemaRelationPtr relations;
442
    int located;
443
    int parsed;
444
    int imported;
445
    int preserveDoc;
446
    xmlSchemaItemListPtr globals;
447
    xmlSchemaItemListPtr locals;
448
    /* The imported schema. */
449
    xmlSchemaPtr schema;
450
};
451
452
/*
453
* (extends xmlSchemaBucket)
454
*/
455
typedef struct _xmlSchemaInclude xmlSchemaInclude;
456
typedef xmlSchemaInclude *xmlSchemaIncludePtr;
457
struct _xmlSchemaInclude {
458
    int type;
459
    int flags;
460
    const xmlChar *schemaLocation;
461
    const xmlChar *origTargetNamespace;
462
    const xmlChar *targetNamespace;
463
    xmlDocPtr doc;
464
    xmlSchemaSchemaRelationPtr relations;
465
    int located;
466
    int parsed;
467
    int imported;
468
    int preserveDoc;
469
    xmlSchemaItemListPtr globals; /* Global components. */
470
    xmlSchemaItemListPtr locals; /* Local components. */
471
472
    /* The owning main or import schema bucket. */
473
    xmlSchemaImportPtr ownerImport;
474
};
475
476
/**
477
 * xmlSchemaBasicItem:
478
 *
479
 * The abstract base type for schema components.
480
 */
481
typedef struct _xmlSchemaBasicItem xmlSchemaBasicItem;
482
typedef xmlSchemaBasicItem *xmlSchemaBasicItemPtr;
483
struct _xmlSchemaBasicItem {
484
    xmlSchemaTypeType type;
485
    void *dummy; /* Fix alignment issues */
486
};
487
488
/**
489
 * xmlSchemaAnnotItem:
490
 *
491
 * The abstract base type for annotated schema components.
492
 * (Extends xmlSchemaBasicItem)
493
 */
494
typedef struct _xmlSchemaAnnotItem xmlSchemaAnnotItem;
495
typedef xmlSchemaAnnotItem *xmlSchemaAnnotItemPtr;
496
struct _xmlSchemaAnnotItem {
497
    xmlSchemaTypeType type;
498
    xmlSchemaAnnotPtr annot;
499
};
500
501
/**
502
 * xmlSchemaTreeItem:
503
 *
504
 * The abstract base type for tree-like structured schema components.
505
 * (Extends xmlSchemaAnnotItem)
506
 */
507
typedef struct _xmlSchemaTreeItem xmlSchemaTreeItem;
508
typedef xmlSchemaTreeItem *xmlSchemaTreeItemPtr;
509
struct _xmlSchemaTreeItem {
510
    xmlSchemaTypeType type;
511
    xmlSchemaAnnotPtr annot;
512
    xmlSchemaTreeItemPtr next;
513
    xmlSchemaTreeItemPtr children;
514
};
515
516
517
0
#define XML_SCHEMA_ATTR_USE_FIXED 1<<0
518
/**
519
 * xmlSchemaAttributeUsePtr:
520
 *
521
 * The abstract base type for tree-like structured schema components.
522
 * (Extends xmlSchemaTreeItem)
523
 */
524
typedef struct _xmlSchemaAttributeUse xmlSchemaAttributeUse;
525
typedef xmlSchemaAttributeUse *xmlSchemaAttributeUsePtr;
526
struct _xmlSchemaAttributeUse {
527
    xmlSchemaTypeType type;
528
    xmlSchemaAnnotPtr annot;
529
    xmlSchemaAttributeUsePtr next; /* The next attr. use. */
530
    /*
531
    * The attr. decl. OR a QName-ref. to an attr. decl. OR
532
    * a QName-ref. to an attribute group definition.
533
    */
534
    xmlSchemaAttributePtr attrDecl;
535
536
    int flags;
537
    xmlNodePtr node;
538
    int occurs; /* required, optional */
539
    const xmlChar * defValue;
540
    xmlSchemaValPtr defVal;
541
};
542
543
/**
544
 * xmlSchemaAttributeUseProhibPtr:
545
 *
546
 * A helper component to reflect attribute prohibitions.
547
 * (Extends xmlSchemaBasicItem)
548
 */
549
typedef struct _xmlSchemaAttributeUseProhib xmlSchemaAttributeUseProhib;
550
typedef xmlSchemaAttributeUseProhib *xmlSchemaAttributeUseProhibPtr;
551
struct _xmlSchemaAttributeUseProhib {
552
    xmlSchemaTypeType type; /* == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB */
553
    xmlNodePtr node;
554
    const xmlChar *name;
555
    const xmlChar *targetNamespace;
556
    int isRef;
557
};
558
559
/**
560
 * xmlSchemaRedef:
561
 */
562
typedef struct _xmlSchemaRedef xmlSchemaRedef;
563
typedef xmlSchemaRedef *xmlSchemaRedefPtr;
564
struct _xmlSchemaRedef {
565
    xmlSchemaRedefPtr next;
566
    xmlSchemaBasicItemPtr item; /* The redefining component. */
567
    xmlSchemaBasicItemPtr reference; /* The referencing component. */
568
    xmlSchemaBasicItemPtr target; /* The to-be-redefined component. */
569
    const xmlChar *refName; /* The name of the to-be-redefined component. */
570
    const xmlChar *refTargetNs; /* The target namespace of the
571
                                   to-be-redefined comp. */
572
    xmlSchemaBucketPtr targetBucket; /* The redefined schema. */
573
};
574
575
/**
576
 * xmlSchemaConstructionCtxt:
577
 */
578
typedef struct _xmlSchemaConstructionCtxt xmlSchemaConstructionCtxt;
579
typedef xmlSchemaConstructionCtxt *xmlSchemaConstructionCtxtPtr;
580
struct _xmlSchemaConstructionCtxt {
581
    xmlSchemaPtr mainSchema; /* The main schema. */
582
    xmlSchemaBucketPtr mainBucket; /* The main schema bucket */
583
    xmlDictPtr dict;
584
    xmlSchemaItemListPtr buckets; /* List of schema buckets. */
585
    /* xmlSchemaItemListPtr relations; */ /* List of schema relations. */
586
    xmlSchemaBucketPtr bucket; /* The current schema bucket */
587
    xmlSchemaItemListPtr pending; /* All Components of all schemas that
588
                                     need to be fixed. */
589
    xmlHashTablePtr substGroups;
590
    xmlSchemaRedefPtr redefs;
591
    xmlSchemaRedefPtr lastRedef;
592
};
593
594
#define XML_SCHEMAS_PARSE_ERROR   1
595
0
#define SCHEMAS_PARSE_OPTIONS XML_PARSE_NOENT
596
597
struct _xmlSchemaParserCtxt {
598
    int type;
599
    void *errCtxt;             /* user specific error context */
600
    xmlSchemaValidityErrorFunc error;   /* the callback in case of errors */
601
    xmlSchemaValidityWarningFunc warning;       /* the callback in case of warning */
602
    int err;
603
    int nberrors;
604
    xmlStructuredErrorFunc serror;
605
606
    xmlSchemaConstructionCtxtPtr constructor;
607
    int ownsConstructor; /* TODO: Move this to parser *flags*. */
608
609
    /* xmlSchemaPtr topschema;  */
610
    /* xmlHashTablePtr namespaces;  */
611
612
    xmlSchemaPtr schema;        /* The main schema in use */
613
    int counter;
614
615
    const xmlChar *URL;
616
    xmlDocPtr doc;
617
    int preserve;   /* Whether the doc should be freed  */
618
619
    const char *buffer;
620
    int size;
621
622
    /*
623
     * Used to build complex element content models
624
     */
625
    xmlAutomataPtr am;
626
    xmlAutomataStatePtr start;
627
    xmlAutomataStatePtr end;
628
    xmlAutomataStatePtr state;
629
630
    xmlDictPtr dict;    /* dictionary for interned string names */
631
    xmlSchemaTypePtr ctxtType; /* The current context simple/complex type */
632
    int options;
633
    xmlSchemaValidCtxtPtr vctxt;
634
    int isS4S;
635
    int isRedefine;
636
    int xsiAssemble;
637
    int stop; /* If the parser should stop; i.e. a critical error. */
638
    const xmlChar *targetNamespace;
639
    xmlSchemaBucketPtr redefined; /* The schema to be redefined. */
640
641
    xmlSchemaRedefPtr redef; /* Used for redefinitions. */
642
    int redefCounter; /* Used for redefinitions. */
643
    xmlSchemaItemListPtr attrProhibs;
644
645
    xmlResourceLoader resourceLoader;
646
    void *resourceCtxt;
647
};
648
649
/**
650
 * xmlSchemaQNameRef:
651
 *
652
 * A component reference item (not a schema component)
653
 * (Extends xmlSchemaBasicItem)
654
 */
655
typedef struct _xmlSchemaQNameRef xmlSchemaQNameRef;
656
typedef xmlSchemaQNameRef *xmlSchemaQNameRefPtr;
657
struct _xmlSchemaQNameRef {
658
    xmlSchemaTypeType type;
659
    xmlSchemaBasicItemPtr item; /* The resolved referenced item. */
660
    xmlSchemaTypeType itemType;
661
    const xmlChar *name;
662
    const xmlChar *targetNamespace;
663
    xmlNodePtr node;
664
};
665
666
/**
667
 * xmlSchemaParticle:
668
 *
669
 * A particle component.
670
 * (Extends xmlSchemaTreeItem)
671
 */
672
typedef struct _xmlSchemaParticle xmlSchemaParticle;
673
typedef xmlSchemaParticle *xmlSchemaParticlePtr;
674
struct _xmlSchemaParticle {
675
    xmlSchemaTypeType type;
676
    xmlSchemaAnnotPtr annot;
677
    xmlSchemaTreeItemPtr next; /* next particle */
678
    xmlSchemaTreeItemPtr children; /* the "term" (e.g. a model group,
679
  a group definition, a XML_SCHEMA_EXTRA_QNAMEREF (if a reference),
680
        etc.) */
681
    int minOccurs;
682
    int maxOccurs;
683
    xmlNodePtr node;
684
};
685
686
/**
687
 * xmlSchemaModelGroup:
688
 *
689
 * A model group component.
690
 * (Extends xmlSchemaTreeItem)
691
 */
692
typedef struct _xmlSchemaModelGroup xmlSchemaModelGroup;
693
typedef xmlSchemaModelGroup *xmlSchemaModelGroupPtr;
694
struct _xmlSchemaModelGroup {
695
    xmlSchemaTypeType type; /* XML_SCHEMA_TYPE_SEQUENCE, XML_SCHEMA_TYPE_CHOICE, XML_SCHEMA_TYPE_ALL */
696
    xmlSchemaAnnotPtr annot;
697
    xmlSchemaTreeItemPtr next; /* not used */
698
    xmlSchemaTreeItemPtr children; /* first particle (OR "element decl" OR "wildcard") */
699
    xmlNodePtr node;
700
};
701
702
0
#define XML_SCHEMA_MODEL_GROUP_DEF_MARKED 1<<0
703
0
#define XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED 1<<1
704
/**
705
 * xmlSchemaModelGroupDef:
706
 *
707
 * A model group definition component.
708
 * (Extends xmlSchemaTreeItem)
709
 */
710
typedef struct _xmlSchemaModelGroupDef xmlSchemaModelGroupDef;
711
typedef xmlSchemaModelGroupDef *xmlSchemaModelGroupDefPtr;
712
struct _xmlSchemaModelGroupDef {
713
    xmlSchemaTypeType type; /* XML_SCHEMA_TYPE_GROUP */
714
    xmlSchemaAnnotPtr annot;
715
    xmlSchemaTreeItemPtr next; /* not used */
716
    xmlSchemaTreeItemPtr children; /* the "model group" */
717
    const xmlChar *name;
718
    const xmlChar *targetNamespace;
719
    xmlNodePtr node;
720
    int flags;
721
};
722
723
typedef struct _xmlSchemaIDC xmlSchemaIDC;
724
typedef xmlSchemaIDC *xmlSchemaIDCPtr;
725
726
/**
727
 * xmlSchemaIDCSelect:
728
 *
729
 * The identity-constraint "field" and "selector" item, holding the
730
 * XPath expression.
731
 */
732
typedef struct _xmlSchemaIDCSelect xmlSchemaIDCSelect;
733
typedef xmlSchemaIDCSelect *xmlSchemaIDCSelectPtr;
734
struct _xmlSchemaIDCSelect {
735
    xmlSchemaIDCSelectPtr next;
736
    xmlSchemaIDCPtr idc;
737
    int index; /* an index position if significant for IDC key-sequences */
738
    const xmlChar *xpath; /* the XPath expression */
739
    void *xpathComp; /* the compiled XPath expression */
740
};
741
742
/**
743
 * xmlSchemaIDC:
744
 *
745
 * The identity-constraint definition component.
746
 * (Extends xmlSchemaAnnotItem)
747
 */
748
749
struct _xmlSchemaIDC {
750
    xmlSchemaTypeType type;
751
    xmlSchemaAnnotPtr annot;
752
    xmlSchemaIDCPtr next;
753
    xmlNodePtr node;
754
    const xmlChar *name;
755
    const xmlChar *targetNamespace;
756
    xmlSchemaIDCSelectPtr selector;
757
    xmlSchemaIDCSelectPtr fields;
758
    int nbFields;
759
    xmlSchemaQNameRefPtr ref;
760
};
761
762
/**
763
 * xmlSchemaIDCAug:
764
 *
765
 * The augmented IDC information used for validation.
766
 */
767
typedef struct _xmlSchemaIDCAug xmlSchemaIDCAug;
768
typedef xmlSchemaIDCAug *xmlSchemaIDCAugPtr;
769
struct _xmlSchemaIDCAug {
770
    xmlSchemaIDCAugPtr next; /* next in a list */
771
    xmlSchemaIDCPtr def; /* the IDC definition */
772
    int keyrefDepth; /* the lowest tree level to which IDC
773
                        tables need to be bubbled upwards */
774
};
775
776
/**
777
 * xmlSchemaPSVIIDCKeySequence:
778
 *
779
 * The key sequence of a node table item.
780
 */
781
typedef struct _xmlSchemaPSVIIDCKey xmlSchemaPSVIIDCKey;
782
typedef xmlSchemaPSVIIDCKey *xmlSchemaPSVIIDCKeyPtr;
783
struct _xmlSchemaPSVIIDCKey {
784
    xmlSchemaTypePtr type;
785
    xmlSchemaValPtr val;
786
};
787
788
/**
789
 * xmlSchemaPSVIIDCNode:
790
 *
791
 * The node table item of a node table.
792
 */
793
typedef struct _xmlSchemaPSVIIDCNode xmlSchemaPSVIIDCNode;
794
typedef xmlSchemaPSVIIDCNode *xmlSchemaPSVIIDCNodePtr;
795
struct _xmlSchemaPSVIIDCNode {
796
    xmlNodePtr node;
797
    xmlSchemaPSVIIDCKeyPtr *keys;
798
    int nodeLine;
799
    int nodeQNameID;
800
801
};
802
803
/**
804
 * xmlSchemaPSVIIDCBinding:
805
 *
806
 * The identity-constraint binding item of the [identity-constraint table].
807
 */
808
typedef struct _xmlSchemaPSVIIDCBinding xmlSchemaPSVIIDCBinding;
809
typedef xmlSchemaPSVIIDCBinding *xmlSchemaPSVIIDCBindingPtr;
810
struct _xmlSchemaPSVIIDCBinding {
811
    xmlSchemaPSVIIDCBindingPtr next; /* next binding of a specific node */
812
    xmlSchemaIDCPtr definition; /* the IDC definition */
813
    xmlSchemaPSVIIDCNodePtr *nodeTable; /* array of key-sequences */
814
    int nbNodes; /* number of entries in the node table */
815
    int sizeNodes; /* size of the node table */
816
    xmlSchemaItemListPtr dupls;
817
};
818
819
820
0
#define XPATH_STATE_OBJ_TYPE_IDC_SELECTOR 1
821
0
#define XPATH_STATE_OBJ_TYPE_IDC_FIELD 2
822
823
#define XPATH_STATE_OBJ_MATCHES -2
824
#define XPATH_STATE_OBJ_BLOCKED -3
825
826
typedef struct _xmlSchemaIDCMatcher xmlSchemaIDCMatcher;
827
typedef xmlSchemaIDCMatcher *xmlSchemaIDCMatcherPtr;
828
829
/**
830
 * xmlSchemaIDCStateObj:
831
 *
832
 * The state object used to evaluate XPath expressions.
833
 */
834
typedef struct _xmlSchemaIDCStateObj xmlSchemaIDCStateObj;
835
typedef xmlSchemaIDCStateObj *xmlSchemaIDCStateObjPtr;
836
struct _xmlSchemaIDCStateObj {
837
    int type;
838
    xmlSchemaIDCStateObjPtr next; /* next if in a list */
839
    int depth; /* depth of creation */
840
    int *history; /* list of (depth, state-id) tuples */
841
    int nbHistory;
842
    int sizeHistory;
843
    xmlSchemaIDCMatcherPtr matcher; /* the correspondent field/selector
844
                                       matcher */
845
    xmlSchemaIDCSelectPtr sel;
846
    void *xpathCtxt;
847
};
848
849
0
#define IDC_MATCHER 0
850
851
/**
852
 * xmlSchemaIDCMatcher:
853
 *
854
 * Used to evaluate IDC selectors (and fields).
855
 */
856
struct _xmlSchemaIDCMatcher {
857
    int type;
858
    int depth; /* the tree depth at creation time */
859
    xmlSchemaIDCMatcherPtr next; /* next in the list */
860
    xmlSchemaIDCMatcherPtr nextCached; /* next in the cache list */
861
    xmlSchemaIDCAugPtr aidc; /* the augmented IDC item */
862
    int idcType;
863
    xmlSchemaPSVIIDCKeyPtr **keySeqs; /* the key-sequences of the target
864
                                         elements */
865
    int sizeKeySeqs;
866
    xmlSchemaItemListPtr targets; /* list of target-node
867
                                     (xmlSchemaPSVIIDCNodePtr) entries */
868
    xmlHashTablePtr htab;
869
};
870
871
/*
872
* Element info flags.
873
*/
874
0
#define XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES  (1<<0)
875
0
#define XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES (1<<1)
876
0
#define XML_SCHEMA_ELEM_INFO_NILLED            (1<<2)
877
0
#define XML_SCHEMA_ELEM_INFO_LOCAL_TYPE        (1<<3)
878
879
0
#define XML_SCHEMA_NODE_INFO_VALUE_NEEDED      (1<<4)
880
0
#define XML_SCHEMA_ELEM_INFO_EMPTY             (1<<5)
881
#define XML_SCHEMA_ELEM_INFO_HAS_CONTENT       (1<<6)
882
883
0
#define XML_SCHEMA_ELEM_INFO_HAS_ELEM_CONTENT  (1<<7)
884
0
#define XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT   (1<<8)
885
0
#define XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED  (1<<9)
886
0
#define XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE      (1<<10)
887
888
/**
889
 * xmlSchemaNodeInfo:
890
 *
891
 * Holds information of an element node.
892
 */
893
struct _xmlSchemaNodeInfo {
894
    int nodeType;
895
    xmlNodePtr node;
896
    int nodeLine;
897
    const xmlChar *localName;
898
    const xmlChar *nsName;
899
    const xmlChar *value;
900
    xmlSchemaValPtr val; /* the pre-computed value if any */
901
    xmlSchemaTypePtr typeDef; /* the complex/simple type definition if any */
902
903
    int flags; /* combination of node info flags */
904
905
    int valNeeded;
906
    int normVal;
907
908
    xmlSchemaElementPtr decl; /* the element/attribute declaration */
909
    int depth;
910
    xmlSchemaPSVIIDCBindingPtr idcTable; /* the table of PSVI IDC bindings
911
                                            for the scope element*/
912
    xmlSchemaIDCMatcherPtr idcMatchers; /* the IDC matchers for the scope
913
                                           element */
914
    xmlRegExecCtxtPtr regexCtxt;
915
916
    const xmlChar **nsBindings; /* Namespace bindings on this element */
917
    int nbNsBindings;
918
    int sizeNsBindings;
919
920
    int hasKeyrefs;
921
    int appliedXPath; /* Indicates that an XPath has been applied. */
922
};
923
924
0
#define XML_SCHEMAS_ATTR_UNKNOWN 1
925
0
#define XML_SCHEMAS_ATTR_ASSESSED 2
926
#define XML_SCHEMAS_ATTR_PROHIBITED 3
927
0
#define XML_SCHEMAS_ATTR_ERR_MISSING 4
928
0
#define XML_SCHEMAS_ATTR_INVALID_VALUE 5
929
0
#define XML_SCHEMAS_ATTR_ERR_NO_TYPE 6
930
0
#define XML_SCHEMAS_ATTR_ERR_FIXED_VALUE 7
931
0
#define XML_SCHEMAS_ATTR_DEFAULT 8
932
#define XML_SCHEMAS_ATTR_VALIDATE_VALUE 9
933
0
#define XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL 10
934
#define XML_SCHEMAS_ATTR_HAS_ATTR_USE 11
935
#define XML_SCHEMAS_ATTR_HAS_ATTR_DECL 12
936
0
#define XML_SCHEMAS_ATTR_WILD_SKIP 13
937
0
#define XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL 14
938
0
#define XML_SCHEMAS_ATTR_ERR_WILD_DUPLICATE_ID 15
939
0
#define XML_SCHEMAS_ATTR_ERR_WILD_AND_USE_ID 16
940
0
#define XML_SCHEMAS_ATTR_META 17
941
/*
942
* @metaType values of xmlSchemaAttrInfo.
943
*/
944
0
#define XML_SCHEMA_ATTR_INFO_META_XSI_TYPE 1
945
0
#define XML_SCHEMA_ATTR_INFO_META_XSI_NIL 2
946
0
#define XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC 3
947
0
#define XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC 4
948
0
#define XML_SCHEMA_ATTR_INFO_META_XMLNS 5
949
950
typedef struct _xmlSchemaAttrInfo xmlSchemaAttrInfo;
951
typedef xmlSchemaAttrInfo *xmlSchemaAttrInfoPtr;
952
struct _xmlSchemaAttrInfo {
953
    int nodeType;
954
    xmlNodePtr node;
955
    int nodeLine;
956
    const xmlChar *localName;
957
    const xmlChar *nsName;
958
    const xmlChar *value;
959
    xmlSchemaValPtr val; /* the pre-computed value if any */
960
    xmlSchemaTypePtr typeDef; /* the complex/simple type definition if any */
961
    int flags; /* combination of node info flags */
962
963
    xmlSchemaAttributePtr decl; /* the attribute declaration */
964
    xmlSchemaAttributeUsePtr use;  /* the attribute use */
965
    int state;
966
    int metaType;
967
    const xmlChar *vcValue; /* the value constraint value */
968
    xmlSchemaNodeInfoPtr parent;
969
};
970
971
972
0
#define XML_SCHEMA_VALID_CTXT_FLAG_STREAM 1
973
/**
974
 * xmlSchemaValidCtxt:
975
 *
976
 * A Schemas validation context
977
 */
978
struct _xmlSchemaValidCtxt {
979
    int type;
980
    void *errCtxt;             /* user specific data block */
981
    xmlSchemaValidityErrorFunc error;   /* the callback in case of errors */
982
    xmlSchemaValidityWarningFunc warning; /* the callback in case of warning */
983
    xmlStructuredErrorFunc serror;
984
985
    xmlSchemaPtr schema;        /* The schema in use */
986
    xmlDocPtr doc;
987
    xmlParserInputBufferPtr input;
988
    xmlCharEncoding enc;
989
    xmlSAXHandlerPtr sax;
990
    xmlParserCtxtPtr parserCtxt;
991
    void *user_data; /* TODO: What is this for? */
992
    char *filename;
993
994
    int err;
995
    int nberrors;
996
997
    xmlNodePtr node;
998
    xmlNodePtr cur;
999
    /* xmlSchemaTypePtr type; */
1000
1001
    xmlRegExecCtxtPtr regexp;
1002
    xmlSchemaValPtr value;
1003
1004
    int valueWS;
1005
    int options;
1006
    xmlNodePtr validationRoot;
1007
    xmlSchemaParserCtxtPtr pctxt;
1008
    int xsiAssemble;
1009
1010
    int depth;
1011
    xmlSchemaNodeInfoPtr *elemInfos; /* array of element information */
1012
    int sizeElemInfos;
1013
    xmlSchemaNodeInfoPtr inode; /* the current element information */
1014
1015
    xmlSchemaIDCAugPtr aidcs; /* a list of augmented IDC information */
1016
1017
    xmlSchemaIDCStateObjPtr xpathStates; /* first active state object. */
1018
    xmlSchemaIDCStateObjPtr xpathStatePool; /* first stored state object. */
1019
    xmlSchemaIDCMatcherPtr idcMatcherCache; /* Cache for IDC matcher objects. */
1020
1021
    xmlSchemaPSVIIDCNodePtr *idcNodes; /* list of all IDC node-table entries*/
1022
    int nbIdcNodes;
1023
    int sizeIdcNodes;
1024
1025
    xmlSchemaPSVIIDCKeyPtr *idcKeys; /* list of all IDC node-table entries */
1026
    int nbIdcKeys;
1027
    int sizeIdcKeys;
1028
1029
    int flags;
1030
1031
    xmlDictPtr dict;
1032
1033
#ifdef LIBXML_READER_ENABLED
1034
    xmlTextReaderPtr reader;
1035
#endif
1036
1037
    xmlSchemaAttrInfoPtr *attrInfos;
1038
    int nbAttrInfos;
1039
    int sizeAttrInfos;
1040
1041
    int skipDepth;
1042
    xmlSchemaItemListPtr nodeQNames;
1043
    int hasKeyrefs;
1044
    int createIDCNodeTables;
1045
    int psviExposeIDCNodeTables;
1046
1047
    /* Locator for error reporting in streaming mode */
1048
    xmlSchemaValidityLocatorFunc locFunc;
1049
    void *locCtxt;
1050
};
1051
1052
/**
1053
 * xmlSchemaSubstGroup:
1054
 *
1055
 *
1056
 */
1057
typedef struct _xmlSchemaSubstGroup xmlSchemaSubstGroup;
1058
typedef xmlSchemaSubstGroup *xmlSchemaSubstGroupPtr;
1059
struct _xmlSchemaSubstGroup {
1060
    xmlSchemaElementPtr head;
1061
    xmlSchemaItemListPtr members;
1062
};
1063
1064
/**
1065
 * xmlIDCHashEntry:
1066
 *
1067
 * an entry in hash tables to quickly look up keys/uniques
1068
 */
1069
typedef struct _xmlIDCHashEntry xmlIDCHashEntry;
1070
typedef xmlIDCHashEntry *xmlIDCHashEntryPtr;
1071
struct _xmlIDCHashEntry {
1072
    xmlIDCHashEntryPtr next; /* next item with same hash */
1073
    int index;               /* index into associated item list */
1074
};
1075
1076
/************************************************************************
1077
 *                  *
1078
 *      Some predeclarations        *
1079
 *                  *
1080
 ************************************************************************/
1081
1082
static int xmlSchemaParseInclude(xmlSchemaParserCtxtPtr ctxt,
1083
                                 xmlSchemaPtr schema,
1084
                                 xmlNodePtr node);
1085
static int xmlSchemaParseRedefine(xmlSchemaParserCtxtPtr ctxt,
1086
                                 xmlSchemaPtr schema,
1087
                                 xmlNodePtr node);
1088
static int
1089
xmlSchemaTypeFixup(xmlSchemaTypePtr type,
1090
                   xmlSchemaAbstractCtxtPtr ctxt);
1091
static const xmlChar *
1092
xmlSchemaFacetTypeToString(xmlSchemaTypeType type);
1093
static int
1094
xmlSchemaParseImport(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
1095
                     xmlNodePtr node);
1096
static int
1097
xmlSchemaCheckFacetValues(xmlSchemaTypePtr typeDecl,
1098
                       xmlSchemaParserCtxtPtr ctxt);
1099
static void
1100
xmlSchemaClearValidCtxt(xmlSchemaValidCtxtPtr vctxt);
1101
static xmlSchemaWhitespaceValueType
1102
xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type);
1103
static xmlSchemaTreeItemPtr
1104
xmlSchemaParseModelGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
1105
       xmlNodePtr node, xmlSchemaTypeType type,
1106
       int withParticle);
1107
static const xmlChar *
1108
xmlSchemaGetComponentTypeStr(xmlSchemaBasicItemPtr item);
1109
static xmlSchemaTypeLinkPtr
1110
xmlSchemaGetUnionSimpleTypeMemberTypes(xmlSchemaTypePtr type);
1111
static void
1112
xmlSchemaInternalErr(xmlSchemaAbstractCtxtPtr actxt,
1113
         const char *funcName,
1114
         const char *message) LIBXML_ATTR_FORMAT(3,0);
1115
static int
1116
xmlSchemaCheckCOSSTDerivedOK(xmlSchemaAbstractCtxtPtr ctxt,
1117
           xmlSchemaTypePtr type,
1118
           xmlSchemaTypePtr baseType,
1119
           int subset);
1120
static void
1121
xmlSchemaCheckElementDeclComponent(xmlSchemaElementPtr elemDecl,
1122
           xmlSchemaParserCtxtPtr ctxt);
1123
static void
1124
xmlSchemaComponentListFree(xmlSchemaItemListPtr list);
1125
static xmlSchemaQNameRefPtr
1126
xmlSchemaParseAttributeGroupRef(xmlSchemaParserCtxtPtr pctxt,
1127
        xmlSchemaPtr schema,
1128
        xmlNodePtr node);
1129
1130
/************************************************************************
1131
 *                  *
1132
 *      Helper functions              *
1133
 *                  *
1134
 ************************************************************************/
1135
1136
/**
1137
 * xmlSchemaItemTypeToStr:
1138
 * @type: the type of the schema item
1139
 *
1140
 * Returns the component name of a schema item.
1141
 */
1142
static const xmlChar *
1143
xmlSchemaItemTypeToStr(xmlSchemaTypeType type)
1144
0
{
1145
0
    switch (type) {
1146
0
  case XML_SCHEMA_TYPE_BASIC:
1147
0
      return(BAD_CAST "simple type definition");
1148
0
  case XML_SCHEMA_TYPE_SIMPLE:
1149
0
      return(BAD_CAST "simple type definition");
1150
0
  case XML_SCHEMA_TYPE_COMPLEX:
1151
0
      return(BAD_CAST "complex type definition");
1152
0
  case XML_SCHEMA_TYPE_ELEMENT:
1153
0
      return(BAD_CAST "element declaration");
1154
0
  case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
1155
0
      return(BAD_CAST "attribute use");
1156
0
  case XML_SCHEMA_TYPE_ATTRIBUTE:
1157
0
      return(BAD_CAST "attribute declaration");
1158
0
  case XML_SCHEMA_TYPE_GROUP:
1159
0
      return(BAD_CAST "model group definition");
1160
0
  case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
1161
0
      return(BAD_CAST "attribute group definition");
1162
0
  case XML_SCHEMA_TYPE_NOTATION:
1163
0
      return(BAD_CAST "notation declaration");
1164
0
  case XML_SCHEMA_TYPE_SEQUENCE:
1165
0
      return(BAD_CAST "model group (sequence)");
1166
0
  case XML_SCHEMA_TYPE_CHOICE:
1167
0
      return(BAD_CAST "model group (choice)");
1168
0
  case XML_SCHEMA_TYPE_ALL:
1169
0
      return(BAD_CAST "model group (all)");
1170
0
  case XML_SCHEMA_TYPE_PARTICLE:
1171
0
      return(BAD_CAST "particle");
1172
0
  case XML_SCHEMA_TYPE_IDC_UNIQUE:
1173
0
      return(BAD_CAST "unique identity-constraint");
1174
      /* return(BAD_CAST "IDC (unique)"); */
1175
0
  case XML_SCHEMA_TYPE_IDC_KEY:
1176
0
      return(BAD_CAST "key identity-constraint");
1177
      /* return(BAD_CAST "IDC (key)"); */
1178
0
  case XML_SCHEMA_TYPE_IDC_KEYREF:
1179
0
      return(BAD_CAST "keyref identity-constraint");
1180
      /* return(BAD_CAST "IDC (keyref)"); */
1181
0
  case XML_SCHEMA_TYPE_ANY:
1182
0
      return(BAD_CAST "wildcard (any)");
1183
0
  case XML_SCHEMA_EXTRA_QNAMEREF:
1184
0
      return(BAD_CAST "[helper component] QName reference");
1185
0
  case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB:
1186
0
      return(BAD_CAST "[helper component] attribute use prohibition");
1187
0
  default:
1188
0
      return(BAD_CAST "Not a schema component");
1189
0
    }
1190
0
}
1191
1192
/**
1193
 * xmlSchemaGetComponentTypeStr:
1194
 * @type: the type of the schema item
1195
 *
1196
 * Returns the component name of a schema item.
1197
 */
1198
static const xmlChar *
1199
xmlSchemaGetComponentTypeStr(xmlSchemaBasicItemPtr item)
1200
0
{
1201
0
    switch (item->type) {
1202
0
  case XML_SCHEMA_TYPE_BASIC:
1203
0
      if (WXS_IS_COMPLEX(WXS_TYPE_CAST item))
1204
0
    return(BAD_CAST "complex type definition");
1205
0
      else
1206
0
    return(BAD_CAST "simple type definition");
1207
0
  default:
1208
0
      return(xmlSchemaItemTypeToStr(item->type));
1209
0
    }
1210
0
}
1211
1212
/**
1213
 * xmlSchemaGetComponentNode:
1214
 * @item: a schema component
1215
 *
1216
 * Returns node associated with the schema component.
1217
 * NOTE that such a node need not be available; plus, a component's
1218
 * node need not to reflect the component directly, since there is no
1219
 * one-to-one relationship between the XML Schema representation and
1220
 * the component representation.
1221
 */
1222
static xmlNodePtr
1223
xmlSchemaGetComponentNode(xmlSchemaBasicItemPtr item)
1224
0
{
1225
0
    switch (item->type) {
1226
0
  case XML_SCHEMA_TYPE_ELEMENT:
1227
0
      return (((xmlSchemaElementPtr) item)->node);
1228
0
  case XML_SCHEMA_TYPE_ATTRIBUTE:
1229
0
      return (((xmlSchemaAttributePtr) item)->node);
1230
0
  case XML_SCHEMA_TYPE_COMPLEX:
1231
0
  case XML_SCHEMA_TYPE_SIMPLE:
1232
0
      return (((xmlSchemaTypePtr) item)->node);
1233
0
  case XML_SCHEMA_TYPE_ANY:
1234
0
  case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
1235
0
      return (((xmlSchemaWildcardPtr) item)->node);
1236
0
  case XML_SCHEMA_TYPE_PARTICLE:
1237
0
      return (((xmlSchemaParticlePtr) item)->node);
1238
0
  case XML_SCHEMA_TYPE_SEQUENCE:
1239
0
  case XML_SCHEMA_TYPE_CHOICE:
1240
0
  case XML_SCHEMA_TYPE_ALL:
1241
0
      return (((xmlSchemaModelGroupPtr) item)->node);
1242
0
  case XML_SCHEMA_TYPE_GROUP:
1243
0
      return (((xmlSchemaModelGroupDefPtr) item)->node);
1244
0
  case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
1245
0
      return (((xmlSchemaAttributeGroupPtr) item)->node);
1246
0
  case XML_SCHEMA_TYPE_IDC_UNIQUE:
1247
0
  case XML_SCHEMA_TYPE_IDC_KEY:
1248
0
  case XML_SCHEMA_TYPE_IDC_KEYREF:
1249
0
      return (((xmlSchemaIDCPtr) item)->node);
1250
0
  case XML_SCHEMA_EXTRA_QNAMEREF:
1251
0
      return(((xmlSchemaQNameRefPtr) item)->node);
1252
  /* TODO: What to do with NOTATIONs?
1253
  case XML_SCHEMA_TYPE_NOTATION:
1254
      return (((xmlSchemaNotationPtr) item)->node);
1255
  */
1256
0
  case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
1257
0
      return (((xmlSchemaAttributeUsePtr) item)->node);
1258
0
  default:
1259
0
      return (NULL);
1260
0
    }
1261
0
}
1262
1263
#if 0
1264
/**
1265
 * xmlSchemaGetNextComponent:
1266
 * @item: a schema component
1267
 *
1268
 * Returns the next sibling of the schema component.
1269
 */
1270
static xmlSchemaBasicItemPtr
1271
xmlSchemaGetNextComponent(xmlSchemaBasicItemPtr item)
1272
{
1273
    switch (item->type) {
1274
  case XML_SCHEMA_TYPE_ELEMENT:
1275
      return ((xmlSchemaBasicItemPtr) ((xmlSchemaElementPtr) item)->next);
1276
  case XML_SCHEMA_TYPE_ATTRIBUTE:
1277
      return ((xmlSchemaBasicItemPtr) ((xmlSchemaAttributePtr) item)->next);
1278
  case XML_SCHEMA_TYPE_COMPLEX:
1279
  case XML_SCHEMA_TYPE_SIMPLE:
1280
      return ((xmlSchemaBasicItemPtr) ((xmlSchemaTypePtr) item)->next);
1281
  case XML_SCHEMA_TYPE_ANY:
1282
  case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
1283
      return (NULL);
1284
  case XML_SCHEMA_TYPE_PARTICLE:
1285
      return ((xmlSchemaBasicItemPtr) ((xmlSchemaParticlePtr) item)->next);
1286
  case XML_SCHEMA_TYPE_SEQUENCE:
1287
  case XML_SCHEMA_TYPE_CHOICE:
1288
  case XML_SCHEMA_TYPE_ALL:
1289
      return (NULL);
1290
  case XML_SCHEMA_TYPE_GROUP:
1291
      return (NULL);
1292
  case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
1293
      return ((xmlSchemaBasicItemPtr) ((xmlSchemaAttributeGroupPtr) item)->next);
1294
  case XML_SCHEMA_TYPE_IDC_UNIQUE:
1295
  case XML_SCHEMA_TYPE_IDC_KEY:
1296
  case XML_SCHEMA_TYPE_IDC_KEYREF:
1297
      return ((xmlSchemaBasicItemPtr) ((xmlSchemaIDCPtr) item)->next);
1298
  default:
1299
      return (NULL);
1300
    }
1301
}
1302
#endif
1303
1304
1305
/**
1306
 * xmlSchemaFormatQName:
1307
 * @buf: the string buffer
1308
 * @namespaceName:  the namespace name
1309
 * @localName: the local name
1310
 *
1311
 * Returns the given QName in the format "{namespaceName}localName" or
1312
 * just "localName" if @namespaceName is NULL.
1313
 *
1314
 * Returns the localName if @namespaceName is NULL, a formatted
1315
 * string otherwise.
1316
 */
1317
static const xmlChar*
1318
xmlSchemaFormatQName(xmlChar **buf,
1319
         const xmlChar *namespaceName,
1320
         const xmlChar *localName)
1321
0
{
1322
0
    FREE_AND_NULL(*buf)
1323
0
    if (namespaceName != NULL) {
1324
0
  *buf = xmlStrdup(BAD_CAST "{");
1325
0
  *buf = xmlStrcat(*buf, namespaceName);
1326
0
  *buf = xmlStrcat(*buf, BAD_CAST "}");
1327
0
    }
1328
0
    if (localName != NULL) {
1329
0
  if (namespaceName == NULL)
1330
0
      return(localName);
1331
0
  *buf = xmlStrcat(*buf, localName);
1332
0
    } else {
1333
0
  *buf = xmlStrcat(*buf, BAD_CAST "(NULL)");
1334
0
    }
1335
0
    return ((const xmlChar *) *buf);
1336
0
}
1337
1338
static const xmlChar*
1339
xmlSchemaFormatQNameNs(xmlChar **buf, xmlNsPtr ns, const xmlChar *localName)
1340
0
{
1341
0
    if (ns != NULL)
1342
0
  return (xmlSchemaFormatQName(buf, ns->href, localName));
1343
0
    else
1344
0
  return (xmlSchemaFormatQName(buf, NULL, localName));
1345
0
}
1346
1347
static const xmlChar *
1348
xmlSchemaGetComponentName(xmlSchemaBasicItemPtr item)
1349
0
{
1350
0
    if (item == NULL) {
1351
0
        return (NULL);
1352
0
    }
1353
0
    switch (item->type) {
1354
0
  case XML_SCHEMA_TYPE_ELEMENT:
1355
0
      return (((xmlSchemaElementPtr) item)->name);
1356
0
  case XML_SCHEMA_TYPE_ATTRIBUTE:
1357
0
      return (((xmlSchemaAttributePtr) item)->name);
1358
0
  case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
1359
0
      return (((xmlSchemaAttributeGroupPtr) item)->name);
1360
0
  case XML_SCHEMA_TYPE_BASIC:
1361
0
  case XML_SCHEMA_TYPE_SIMPLE:
1362
0
  case XML_SCHEMA_TYPE_COMPLEX:
1363
0
      return (((xmlSchemaTypePtr) item)->name);
1364
0
  case XML_SCHEMA_TYPE_GROUP:
1365
0
      return (((xmlSchemaModelGroupDefPtr) item)->name);
1366
0
  case XML_SCHEMA_TYPE_IDC_KEY:
1367
0
  case XML_SCHEMA_TYPE_IDC_UNIQUE:
1368
0
  case XML_SCHEMA_TYPE_IDC_KEYREF:
1369
0
      return (((xmlSchemaIDCPtr) item)->name);
1370
0
  case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
1371
0
      if (WXS_ATTRUSE_DECL(item) != NULL) {
1372
0
    return(xmlSchemaGetComponentName(
1373
0
        WXS_BASIC_CAST WXS_ATTRUSE_DECL(item)));
1374
0
      } else
1375
0
    return(NULL);
1376
0
  case XML_SCHEMA_EXTRA_QNAMEREF:
1377
0
      return (((xmlSchemaQNameRefPtr) item)->name);
1378
0
  case XML_SCHEMA_TYPE_NOTATION:
1379
0
      return (((xmlSchemaNotationPtr) item)->name);
1380
0
  default:
1381
      /*
1382
      * Other components cannot have names.
1383
      */
1384
0
      break;
1385
0
    }
1386
0
    return (NULL);
1387
0
}
1388
1389
0
#define xmlSchemaGetQNameRefName(r) (WXS_QNAME_CAST (r))->name
1390
0
#define xmlSchemaGetQNameRefTargetNs(r) (WXS_QNAME_CAST (r))->targetNamespace
1391
/*
1392
static const xmlChar *
1393
xmlSchemaGetQNameRefName(void *ref)
1394
{
1395
    return(((xmlSchemaQNameRefPtr) ref)->name);
1396
}
1397
1398
static const xmlChar *
1399
xmlSchemaGetQNameRefTargetNs(void *ref)
1400
{
1401
    return(((xmlSchemaQNameRefPtr) ref)->targetNamespace);
1402
}
1403
*/
1404
1405
static const xmlChar *
1406
xmlSchemaGetComponentTargetNs(xmlSchemaBasicItemPtr item)
1407
0
{
1408
0
    if (item == NULL) {
1409
0
        return (NULL);
1410
0
    }
1411
0
    switch (item->type) {
1412
0
  case XML_SCHEMA_TYPE_ELEMENT:
1413
0
      return (((xmlSchemaElementPtr) item)->targetNamespace);
1414
0
  case XML_SCHEMA_TYPE_ATTRIBUTE:
1415
0
      return (((xmlSchemaAttributePtr) item)->targetNamespace);
1416
0
  case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
1417
0
      return (((xmlSchemaAttributeGroupPtr) item)->targetNamespace);
1418
0
  case XML_SCHEMA_TYPE_BASIC:
1419
0
      return (BAD_CAST "http://www.w3.org/2001/XMLSchema");
1420
0
  case XML_SCHEMA_TYPE_SIMPLE:
1421
0
  case XML_SCHEMA_TYPE_COMPLEX:
1422
0
      return (((xmlSchemaTypePtr) item)->targetNamespace);
1423
0
  case XML_SCHEMA_TYPE_GROUP:
1424
0
      return (((xmlSchemaModelGroupDefPtr) item)->targetNamespace);
1425
0
  case XML_SCHEMA_TYPE_IDC_KEY:
1426
0
  case XML_SCHEMA_TYPE_IDC_UNIQUE:
1427
0
  case XML_SCHEMA_TYPE_IDC_KEYREF:
1428
0
      return (((xmlSchemaIDCPtr) item)->targetNamespace);
1429
0
  case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
1430
0
      if (WXS_ATTRUSE_DECL(item) != NULL) {
1431
0
    return(xmlSchemaGetComponentTargetNs(
1432
0
        WXS_BASIC_CAST WXS_ATTRUSE_DECL(item)));
1433
0
      }
1434
      /* TODO: Will returning NULL break something? */
1435
0
      break;
1436
0
  case XML_SCHEMA_EXTRA_QNAMEREF:
1437
0
      return (((xmlSchemaQNameRefPtr) item)->targetNamespace);
1438
0
  case XML_SCHEMA_TYPE_NOTATION:
1439
0
      return (((xmlSchemaNotationPtr) item)->targetNamespace);
1440
0
  default:
1441
      /*
1442
      * Other components cannot have names.
1443
      */
1444
0
      break;
1445
0
    }
1446
0
    return (NULL);
1447
0
}
1448
1449
static const xmlChar*
1450
xmlSchemaGetComponentQName(xmlChar **buf,
1451
         void *item)
1452
0
{
1453
0
    return (xmlSchemaFormatQName(buf,
1454
0
  xmlSchemaGetComponentTargetNs((xmlSchemaBasicItemPtr) item),
1455
0
  xmlSchemaGetComponentName((xmlSchemaBasicItemPtr) item)));
1456
0
}
1457
1458
static const xmlChar*
1459
xmlSchemaGetComponentDesignation(xmlChar **buf, void *item)
1460
0
{
1461
0
    xmlChar *str = NULL;
1462
1463
0
    *buf = xmlStrcat(*buf, WXS_ITEM_TYPE_NAME(item));
1464
0
    *buf = xmlStrcat(*buf, BAD_CAST " '");
1465
0
    *buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str,
1466
0
  (xmlSchemaBasicItemPtr) item));
1467
0
    *buf = xmlStrcat(*buf, BAD_CAST "'");
1468
0
    FREE_AND_NULL(str);
1469
0
    return(*buf);
1470
0
}
1471
1472
static const xmlChar*
1473
xmlSchemaGetIDCDesignation(xmlChar **buf, xmlSchemaIDCPtr idc)
1474
0
{
1475
0
    return(xmlSchemaGetComponentDesignation(buf, idc));
1476
0
}
1477
1478
/**
1479
 * xmlSchemaWildcardPCToString:
1480
 * @pc: the type of processContents
1481
 *
1482
 * Returns a string representation of the type of
1483
 * processContents.
1484
 */
1485
static const xmlChar *
1486
xmlSchemaWildcardPCToString(int pc)
1487
0
{
1488
0
    switch (pc) {
1489
0
  case XML_SCHEMAS_ANY_SKIP:
1490
0
      return (BAD_CAST "skip");
1491
0
  case XML_SCHEMAS_ANY_LAX:
1492
0
      return (BAD_CAST "lax");
1493
0
  case XML_SCHEMAS_ANY_STRICT:
1494
0
      return (BAD_CAST "strict");
1495
0
  default:
1496
0
      return (BAD_CAST "invalid process contents");
1497
0
    }
1498
0
}
1499
1500
/**
1501
 * xmlSchemaGetCanonValueWhtspExt:
1502
 * @val: the precomputed value
1503
 * @retValue: the returned value
1504
 * @ws: the whitespace type of the value
1505
 * @for_hash: non-zero if this is supposed to generate a string for hashing
1506
 *
1507
 * Get a the canonical representation of the value.
1508
 * The caller has to free the returned retValue.
1509
 *
1510
 * Returns 0 if the value could be built and -1 in case of
1511
 *         API errors or if the value type is not supported yet.
1512
 */
1513
static int
1514
xmlSchemaGetCanonValueWhtspExt_1(xmlSchemaValPtr val,
1515
               xmlSchemaWhitespaceValueType ws,
1516
               xmlChar **retValue,
1517
         int for_hash)
1518
0
{
1519
0
    int list;
1520
0
    xmlSchemaValType valType;
1521
0
    const xmlChar *value, *value2 = NULL;
1522
1523
1524
0
    if ((retValue == NULL) || (val == NULL))
1525
0
  return (-1);
1526
0
    list = xmlSchemaValueGetNext(val) ? 1 : 0;
1527
0
    *retValue = NULL;
1528
0
    do {
1529
0
  value = NULL;
1530
0
  valType = xmlSchemaGetValType(val);
1531
0
  switch (valType) {
1532
0
      case XML_SCHEMAS_STRING:
1533
0
      case XML_SCHEMAS_NORMSTRING:
1534
0
      case XML_SCHEMAS_ANYSIMPLETYPE:
1535
0
    value = xmlSchemaValueGetAsString(val);
1536
0
    if (value != NULL) {
1537
0
        if (ws == XML_SCHEMA_WHITESPACE_COLLAPSE)
1538
0
      value2 = xmlSchemaCollapseString(value);
1539
0
        else if (ws == XML_SCHEMA_WHITESPACE_REPLACE)
1540
0
      value2 = xmlSchemaWhiteSpaceReplace(value);
1541
0
        if (value2 != NULL)
1542
0
      value = value2;
1543
0
    }
1544
0
    break;
1545
0
      default:
1546
0
    if (xmlSchemaGetCanonValue(val, &value2) == -1) {
1547
0
        if (value2 != NULL)
1548
0
      xmlFree((xmlChar *) value2);
1549
0
        goto internal_error;
1550
0
    }
1551
0
    if (for_hash && valType == XML_SCHEMAS_DECIMAL) {
1552
        /* We can mostly use the canonical value for hashing,
1553
           except in the case of decimal.  There the canonical
1554
           representation requires a trailing '.0' even for
1555
           non-fractional numbers, but for the derived integer
1556
           types it forbids any decimal point.  Nevertheless they
1557
           compare equal if the value is equal.  We need to generate
1558
           the same hash value for this to work, and it's easiest
1559
           to just cut off the useless '.0' suffix for the
1560
           decimal type.  */
1561
0
        int len = xmlStrlen(value2);
1562
0
        if (len > 2 && value2[len-1] == '0' && value2[len-2] == '.')
1563
0
          ((xmlChar*)value2)[len-2] = 0;
1564
0
    }
1565
0
    value = value2;
1566
0
  }
1567
0
  if (*retValue == NULL)
1568
0
      if (value == NULL) {
1569
0
    if (! list)
1570
0
        *retValue = xmlStrdup(BAD_CAST "");
1571
0
      } else
1572
0
    *retValue = xmlStrdup(value);
1573
0
  else if (value != NULL) {
1574
      /* List. */
1575
0
      *retValue = xmlStrcat((xmlChar *) *retValue, BAD_CAST " ");
1576
0
      *retValue = xmlStrcat((xmlChar *) *retValue, value);
1577
0
  }
1578
0
  FREE_AND_NULL(value2)
1579
0
  val = xmlSchemaValueGetNext(val);
1580
0
    } while (val != NULL);
1581
1582
0
    return (0);
1583
0
internal_error:
1584
0
    if (*retValue != NULL)
1585
0
  xmlFree((xmlChar *) (*retValue));
1586
0
    if (value2 != NULL)
1587
0
  xmlFree((xmlChar *) value2);
1588
0
    return (-1);
1589
0
}
1590
1591
static int
1592
xmlSchemaGetCanonValueWhtspExt(xmlSchemaValPtr val,
1593
             xmlSchemaWhitespaceValueType ws,
1594
             xmlChar **retValue)
1595
0
{
1596
0
    return xmlSchemaGetCanonValueWhtspExt_1(val, ws, retValue, 0);
1597
0
}
1598
1599
static int
1600
xmlSchemaGetCanonValueHash(xmlSchemaValPtr val,
1601
         xmlChar **retValue)
1602
0
{
1603
0
    return xmlSchemaGetCanonValueWhtspExt_1(val, XML_SCHEMA_WHITESPACE_COLLAPSE,
1604
0
              retValue, 1);
1605
0
}
1606
1607
/**
1608
 * xmlSchemaFormatItemForReport:
1609
 * @buf: the string buffer
1610
 * @itemDes: the designation of the item
1611
 * @itemName: the name of the item
1612
 * @item: the item as an object
1613
 * @itemNode: the node of the item
1614
 * @local: the local name
1615
 * @parsing: if the function is used during the parse
1616
 *
1617
 * Returns a representation of the given item used
1618
 * for error reports.
1619
 *
1620
 * The following order is used to build the resulting
1621
 * designation if the arguments are not NULL:
1622
 * 1a. If itemDes not NULL -> itemDes
1623
 * 1b. If (itemDes not NULL) and (itemName not NULL)
1624
 *     -> itemDes + itemName
1625
 * 2. If the preceding was NULL and (item not NULL) -> item
1626
 * 3. If the preceding was NULL and (itemNode not NULL) -> itemNode
1627
 *
1628
 * If the itemNode is an attribute node, the name of the attribute
1629
 * will be appended to the result.
1630
 *
1631
 * Returns the formatted string and sets @buf to the resulting value.
1632
 */
1633
static xmlChar*
1634
xmlSchemaFormatItemForReport(xmlChar **buf,
1635
         const xmlChar *itemDes,
1636
         xmlSchemaBasicItemPtr item,
1637
         xmlNodePtr itemNode)
1638
0
{
1639
0
    xmlChar *str = NULL;
1640
0
    int named = 1;
1641
1642
0
    if (*buf != NULL) {
1643
0
  xmlFree(*buf);
1644
0
  *buf = NULL;
1645
0
    }
1646
1647
0
    if (itemDes != NULL) {
1648
0
  *buf = xmlStrdup(itemDes);
1649
0
    } else if (item != NULL) {
1650
0
  switch (item->type) {
1651
0
  case XML_SCHEMA_TYPE_BASIC: {
1652
0
      xmlSchemaTypePtr type = WXS_TYPE_CAST item;
1653
1654
0
      if (WXS_IS_ATOMIC(type))
1655
0
    *buf = xmlStrdup(BAD_CAST "atomic type 'xs:");
1656
0
      else if (WXS_IS_LIST(type))
1657
0
    *buf = xmlStrdup(BAD_CAST "list type 'xs:");
1658
0
      else if (WXS_IS_UNION(type))
1659
0
    *buf = xmlStrdup(BAD_CAST "union type 'xs:");
1660
0
      else
1661
0
    *buf = xmlStrdup(BAD_CAST "simple type 'xs:");
1662
0
      *buf = xmlStrcat(*buf, type->name);
1663
0
      *buf = xmlStrcat(*buf, BAD_CAST "'");
1664
0
      }
1665
0
      break;
1666
0
  case XML_SCHEMA_TYPE_SIMPLE: {
1667
0
      xmlSchemaTypePtr type = WXS_TYPE_CAST item;
1668
1669
0
      if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) {
1670
0
    *buf = xmlStrdup(BAD_CAST"");
1671
0
      } else {
1672
0
    *buf = xmlStrdup(BAD_CAST "local ");
1673
0
      }
1674
0
      if (WXS_IS_ATOMIC(type))
1675
0
    *buf = xmlStrcat(*buf, BAD_CAST "atomic type");
1676
0
      else if (WXS_IS_LIST(type))
1677
0
    *buf = xmlStrcat(*buf, BAD_CAST "list type");
1678
0
      else if (WXS_IS_UNION(type))
1679
0
    *buf = xmlStrcat(*buf, BAD_CAST "union type");
1680
0
      else
1681
0
    *buf = xmlStrcat(*buf, BAD_CAST "simple type");
1682
0
      if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) {
1683
0
    *buf = xmlStrcat(*buf, BAD_CAST " '");
1684
0
    *buf = xmlStrcat(*buf, type->name);
1685
0
    *buf = xmlStrcat(*buf, BAD_CAST "'");
1686
0
      }
1687
0
      }
1688
0
      break;
1689
0
  case XML_SCHEMA_TYPE_COMPLEX: {
1690
0
      xmlSchemaTypePtr type = WXS_TYPE_CAST item;
1691
1692
0
      if (type->flags & XML_SCHEMAS_TYPE_GLOBAL)
1693
0
    *buf = xmlStrdup(BAD_CAST "");
1694
0
      else
1695
0
    *buf = xmlStrdup(BAD_CAST "local ");
1696
0
      *buf = xmlStrcat(*buf, BAD_CAST "complex type");
1697
0
      if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) {
1698
0
    *buf = xmlStrcat(*buf, BAD_CAST " '");
1699
0
    *buf = xmlStrcat(*buf, type->name);
1700
0
    *buf = xmlStrcat(*buf, BAD_CAST "'");
1701
0
      }
1702
0
      }
1703
0
      break;
1704
0
  case XML_SCHEMA_TYPE_ATTRIBUTE_USE: {
1705
0
    xmlSchemaAttributeUsePtr ause;
1706
1707
0
    ause = WXS_ATTR_USE_CAST item;
1708
0
    *buf = xmlStrdup(BAD_CAST "attribute use ");
1709
0
    if (WXS_ATTRUSE_DECL(ause) != NULL) {
1710
0
        *buf = xmlStrcat(*buf, BAD_CAST "'");
1711
0
        *buf = xmlStrcat(*buf,
1712
0
      xmlSchemaGetComponentQName(&str, WXS_ATTRUSE_DECL(ause)));
1713
0
        FREE_AND_NULL(str)
1714
0
      *buf = xmlStrcat(*buf, BAD_CAST "'");
1715
0
    } else {
1716
0
        *buf = xmlStrcat(*buf, BAD_CAST "(unknown)");
1717
0
    }
1718
0
      }
1719
0
      break;
1720
0
  case XML_SCHEMA_TYPE_ATTRIBUTE: {
1721
0
    xmlSchemaAttributePtr attr;
1722
1723
0
    attr = (xmlSchemaAttributePtr) item;
1724
0
    *buf = xmlStrdup(BAD_CAST "attribute decl.");
1725
0
    *buf = xmlStrcat(*buf, BAD_CAST " '");
1726
0
    *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str,
1727
0
        attr->targetNamespace, attr->name));
1728
0
    FREE_AND_NULL(str)
1729
0
        *buf = xmlStrcat(*buf, BAD_CAST "'");
1730
0
      }
1731
0
      break;
1732
0
  case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
1733
0
      xmlSchemaGetComponentDesignation(buf, item);
1734
0
      break;
1735
0
  case XML_SCHEMA_TYPE_ELEMENT: {
1736
0
    xmlSchemaElementPtr elem;
1737
1738
0
    elem = (xmlSchemaElementPtr) item;
1739
0
    *buf = xmlStrdup(BAD_CAST "element decl.");
1740
0
    *buf = xmlStrcat(*buf, BAD_CAST " '");
1741
0
    *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str,
1742
0
        elem->targetNamespace, elem->name));
1743
0
    *buf = xmlStrcat(*buf, BAD_CAST "'");
1744
0
      }
1745
0
      break;
1746
0
  case XML_SCHEMA_TYPE_IDC_UNIQUE:
1747
0
  case XML_SCHEMA_TYPE_IDC_KEY:
1748
0
  case XML_SCHEMA_TYPE_IDC_KEYREF:
1749
0
      if (item->type == XML_SCHEMA_TYPE_IDC_UNIQUE)
1750
0
    *buf = xmlStrdup(BAD_CAST "unique '");
1751
0
      else if (item->type == XML_SCHEMA_TYPE_IDC_KEY)
1752
0
    *buf = xmlStrdup(BAD_CAST "key '");
1753
0
      else
1754
0
    *buf = xmlStrdup(BAD_CAST "keyRef '");
1755
0
      *buf = xmlStrcat(*buf, ((xmlSchemaIDCPtr) item)->name);
1756
0
      *buf = xmlStrcat(*buf, BAD_CAST "'");
1757
0
      break;
1758
0
  case XML_SCHEMA_TYPE_ANY:
1759
0
  case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
1760
0
      *buf = xmlStrdup(xmlSchemaWildcardPCToString(
1761
0
        ((xmlSchemaWildcardPtr) item)->processContents));
1762
0
      *buf = xmlStrcat(*buf, BAD_CAST " wildcard");
1763
0
      break;
1764
0
  case XML_SCHEMA_FACET_MININCLUSIVE:
1765
0
  case XML_SCHEMA_FACET_MINEXCLUSIVE:
1766
0
  case XML_SCHEMA_FACET_MAXINCLUSIVE:
1767
0
  case XML_SCHEMA_FACET_MAXEXCLUSIVE:
1768
0
  case XML_SCHEMA_FACET_TOTALDIGITS:
1769
0
  case XML_SCHEMA_FACET_FRACTIONDIGITS:
1770
0
  case XML_SCHEMA_FACET_PATTERN:
1771
0
  case XML_SCHEMA_FACET_ENUMERATION:
1772
0
  case XML_SCHEMA_FACET_WHITESPACE:
1773
0
  case XML_SCHEMA_FACET_LENGTH:
1774
0
  case XML_SCHEMA_FACET_MAXLENGTH:
1775
0
  case XML_SCHEMA_FACET_MINLENGTH:
1776
0
      *buf = xmlStrdup(BAD_CAST "facet '");
1777
0
      *buf = xmlStrcat(*buf, xmlSchemaFacetTypeToString(item->type));
1778
0
      *buf = xmlStrcat(*buf, BAD_CAST "'");
1779
0
      break;
1780
0
  case XML_SCHEMA_TYPE_GROUP: {
1781
0
    *buf = xmlStrdup(BAD_CAST "model group def.");
1782
0
    *buf = xmlStrcat(*buf, BAD_CAST " '");
1783
0
    *buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str, item));
1784
0
    *buf = xmlStrcat(*buf, BAD_CAST "'");
1785
0
    FREE_AND_NULL(str)
1786
0
      }
1787
0
      break;
1788
0
  case XML_SCHEMA_TYPE_SEQUENCE:
1789
0
  case XML_SCHEMA_TYPE_CHOICE:
1790
0
  case XML_SCHEMA_TYPE_ALL:
1791
0
  case XML_SCHEMA_TYPE_PARTICLE:
1792
0
      *buf = xmlStrdup(WXS_ITEM_TYPE_NAME(item));
1793
0
      break;
1794
0
  case XML_SCHEMA_TYPE_NOTATION: {
1795
0
    *buf = xmlStrdup(WXS_ITEM_TYPE_NAME(item));
1796
0
    *buf = xmlStrcat(*buf, BAD_CAST " '");
1797
0
    *buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str, item));
1798
0
    *buf = xmlStrcat(*buf, BAD_CAST "'");
1799
0
    FREE_AND_NULL(str);
1800
0
      }
1801
            /* Falls through. */
1802
0
  default:
1803
0
      named = 0;
1804
0
  }
1805
0
    } else
1806
0
  named = 0;
1807
1808
0
    if ((named == 0) && (itemNode != NULL)) {
1809
0
  xmlNodePtr elem;
1810
1811
0
  if (itemNode->type == XML_ATTRIBUTE_NODE)
1812
0
      elem = itemNode->parent;
1813
0
  else
1814
0
      elem = itemNode;
1815
0
  *buf = xmlStrdup(BAD_CAST "Element '");
1816
0
  if (elem->ns != NULL) {
1817
0
      *buf = xmlStrcat(*buf,
1818
0
    xmlSchemaFormatQName(&str, elem->ns->href, elem->name));
1819
0
      FREE_AND_NULL(str)
1820
0
  } else
1821
0
      *buf = xmlStrcat(*buf, elem->name);
1822
0
  *buf = xmlStrcat(*buf, BAD_CAST "'");
1823
1824
0
    }
1825
0
    if ((itemNode != NULL) && (itemNode->type == XML_ATTRIBUTE_NODE)) {
1826
0
  *buf = xmlStrcat(*buf, BAD_CAST ", attribute '");
1827
0
  if (itemNode->ns != NULL) {
1828
0
      *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str,
1829
0
    itemNode->ns->href, itemNode->name));
1830
0
      FREE_AND_NULL(str)
1831
0
  } else
1832
0
      *buf = xmlStrcat(*buf, itemNode->name);
1833
0
  *buf = xmlStrcat(*buf, BAD_CAST "'");
1834
0
    }
1835
0
    FREE_AND_NULL(str)
1836
1837
0
    return (xmlEscapeFormatString(buf));
1838
0
}
1839
1840
/**
1841
 * xmlSchemaFormatFacetEnumSet:
1842
 * @buf: the string buffer
1843
 * @type: the type holding the enumeration facets
1844
 *
1845
 * Builds a string consisting of all enumeration elements.
1846
 *
1847
 * Returns a string of all enumeration elements.
1848
 */
1849
static const xmlChar *
1850
xmlSchemaFormatFacetEnumSet(xmlSchemaAbstractCtxtPtr actxt,
1851
          xmlChar **buf, xmlSchemaTypePtr type)
1852
0
{
1853
0
    xmlSchemaFacetPtr facet;
1854
0
    xmlSchemaWhitespaceValueType ws;
1855
0
    xmlChar *value = NULL;
1856
0
    int res, found = 0;
1857
1858
0
    if (*buf != NULL)
1859
0
  xmlFree(*buf);
1860
0
    *buf = NULL;
1861
1862
0
    do {
1863
  /*
1864
  * Use the whitespace type of the base type.
1865
  */
1866
0
  ws = xmlSchemaGetWhiteSpaceFacetValue(type->baseType);
1867
0
  for (facet = type->facets; facet != NULL; facet = facet->next) {
1868
0
      if (facet->type != XML_SCHEMA_FACET_ENUMERATION)
1869
0
    continue;
1870
0
      found = 1;
1871
0
      res = xmlSchemaGetCanonValueWhtspExt(facet->val,
1872
0
    ws, &value);
1873
0
      if (res == -1) {
1874
0
    xmlSchemaInternalErr(actxt,
1875
0
        "xmlSchemaFormatFacetEnumSet",
1876
0
        "compute the canonical lexical representation");
1877
0
    if (*buf != NULL)
1878
0
        xmlFree(*buf);
1879
0
    *buf = NULL;
1880
0
    return (NULL);
1881
0
      }
1882
0
      if (*buf == NULL)
1883
0
    *buf = xmlStrdup(BAD_CAST "'");
1884
0
      else
1885
0
    *buf = xmlStrcat(*buf, BAD_CAST ", '");
1886
0
      *buf = xmlStrcat(*buf, BAD_CAST value);
1887
0
      *buf = xmlStrcat(*buf, BAD_CAST "'");
1888
0
      if (value != NULL) {
1889
0
    xmlFree((xmlChar *)value);
1890
0
    value = NULL;
1891
0
      }
1892
0
  }
1893
  /*
1894
  * The enumeration facet of a type restricts the enumeration
1895
  * facet of the ancestor type; i.e., such restricted enumerations
1896
  * do not belong to the set of the given type. Thus we break
1897
  * on the first found enumeration.
1898
  */
1899
0
  if (found)
1900
0
      break;
1901
0
  type = type->baseType;
1902
0
    } while ((type != NULL) && (type->type != XML_SCHEMA_TYPE_BASIC));
1903
1904
0
    return ((const xmlChar *) *buf);
1905
0
}
1906
1907
/************************************************************************
1908
 *                  *
1909
 *      Error functions               *
1910
 *                  *
1911
 ************************************************************************/
1912
1913
/**
1914
 * xmlSchemaPErrMemory:
1915
 * @node: a context node
1916
 * @extra:  extra information
1917
 *
1918
 * Handle an out of memory condition
1919
 */
1920
static void
1921
xmlSchemaPErrMemory(xmlSchemaParserCtxtPtr ctxt)
1922
0
{
1923
0
    xmlGenericErrorFunc channel = NULL;
1924
0
    xmlStructuredErrorFunc schannel = NULL;
1925
0
    void *data = NULL;
1926
1927
0
    if (ctxt != NULL) {
1928
0
        ctxt->nberrors++;
1929
0
        ctxt->err = XML_ERR_NO_MEMORY;
1930
0
        channel = ctxt->error;
1931
0
        schannel = ctxt->serror;
1932
0
        data = ctxt->errCtxt;
1933
0
    }
1934
1935
0
    xmlRaiseMemoryError(schannel, channel, data, XML_FROM_SCHEMASP, NULL);
1936
0
}
1937
1938
static void LIBXML_ATTR_FORMAT(11,12)
1939
xmlSchemaPErrFull(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int code,
1940
                  xmlErrorLevel level, const char *file, int line,
1941
                  const xmlChar *str1, const xmlChar *str2, const xmlChar *str3,
1942
0
                  int col, const char *msg, ...) {
1943
0
    xmlGenericErrorFunc channel = NULL;
1944
0
    xmlStructuredErrorFunc schannel = NULL;
1945
0
    void *data = NULL;
1946
0
    int res;
1947
0
    va_list ap;
1948
1949
0
    if (ctxt != NULL) {
1950
        /* Don't overwrite memory errors */
1951
0
        if (ctxt->err == XML_ERR_NO_MEMORY)
1952
0
            return;
1953
1954
0
        if (level == XML_ERR_WARNING) {
1955
0
            channel = ctxt->warning;
1956
0
        } else {
1957
0
            ctxt->nberrors++;
1958
0
            ctxt->err = code;
1959
0
            channel = ctxt->error;
1960
0
        }
1961
0
        data = ctxt->errCtxt;
1962
0
        schannel = ctxt->serror;
1963
0
    }
1964
1965
0
    if ((channel == NULL) && (schannel == NULL)) {
1966
0
        channel = xmlGenericError;
1967
0
        data = xmlGenericErrorContext;
1968
0
    }
1969
1970
0
    va_start(ap, msg);
1971
0
    res = xmlVRaiseError(schannel, channel, data, ctxt, node,
1972
0
                         XML_FROM_SCHEMASP, code, level, file, line,
1973
0
                         (const char *) str1,
1974
0
                         (const char *) str2,
1975
0
                         (const char *) str3,
1976
0
                         0, col, msg, ap);
1977
0
    va_end(ap);
1978
1979
0
    if (res < 0)
1980
0
        xmlSchemaPErrMemory(ctxt);
1981
0
}
1982
1983
/**
1984
 * xmlSchemaPErr:
1985
 * @ctxt: the parsing context
1986
 * @node: the context node
1987
 * @error: the error code
1988
 * @msg: the error message
1989
 * @str1: extra data
1990
 * @str2: extra data
1991
 *
1992
 * Handle a parser error
1993
 */
1994
static void LIBXML_ATTR_FORMAT(4,0)
1995
xmlSchemaPErr(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int code,
1996
              const char *msg, const xmlChar * str1, const xmlChar * str2)
1997
0
{
1998
0
    xmlSchemaPErrFull(ctxt, node, code, XML_ERR_ERROR, NULL, 0,
1999
0
                      str1, str2, NULL, 0, msg, str1, str2);
2000
0
}
2001
2002
/**
2003
 * xmlSchemaPErr2:
2004
 * @ctxt: the parsing context
2005
 * @node: the context node
2006
 * @node: the current child
2007
 * @error: the error code
2008
 * @msg: the error message
2009
 * @str1: extra data
2010
 * @str2: extra data
2011
 *
2012
 * Handle a parser error
2013
 */
2014
static void LIBXML_ATTR_FORMAT(5,0)
2015
xmlSchemaPErr2(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
2016
               xmlNodePtr child, int error,
2017
               const char *msg, const xmlChar * str1, const xmlChar * str2)
2018
0
{
2019
0
    if (child != NULL)
2020
0
        xmlSchemaPErr(ctxt, child, error, msg, str1, str2);
2021
0
    else
2022
0
        xmlSchemaPErr(ctxt, node, error, msg, str1, str2);
2023
0
}
2024
2025
2026
/**
2027
 * xmlSchemaPErrExt:
2028
 * @ctxt: the parsing context
2029
 * @node: the context node
2030
 * @error: the error code
2031
 * @strData1: extra data
2032
 * @strData2: extra data
2033
 * @strData3: extra data
2034
 * @msg: the message
2035
 * @str1:  extra parameter for the message display
2036
 * @str2:  extra parameter for the message display
2037
 * @str3:  extra parameter for the message display
2038
 * @str4:  extra parameter for the message display
2039
 * @str5:  extra parameter for the message display
2040
 *
2041
 * Handle a parser error
2042
 */
2043
static void LIBXML_ATTR_FORMAT(7,0)
2044
xmlSchemaPErrExt(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int code,
2045
    const xmlChar * strData1, const xmlChar * strData2,
2046
    const xmlChar * strData3, const char *msg, const xmlChar * str1,
2047
    const xmlChar * str2, const xmlChar * str3, const xmlChar * str4,
2048
    const xmlChar * str5)
2049
0
{
2050
0
    xmlSchemaPErrFull(ctxt, node, code, XML_ERR_ERROR, NULL, 0,
2051
0
                      strData1, strData2, strData3, 0,
2052
0
                      msg, str1, str2, str3, str4, str5);
2053
0
}
2054
2055
/************************************************************************
2056
 *                  *
2057
 *      Allround error functions      *
2058
 *                  *
2059
 ************************************************************************/
2060
2061
/**
2062
 * xmlSchemaVTypeErrMemory:
2063
 * @node: a context node
2064
 * @extra:  extra information
2065
 *
2066
 * Handle an out of memory condition
2067
 */
2068
static void
2069
xmlSchemaVErrMemory(xmlSchemaValidCtxtPtr ctxt)
2070
0
{
2071
0
    xmlGenericErrorFunc channel = NULL;
2072
0
    xmlStructuredErrorFunc schannel = NULL;
2073
0
    void *data = NULL;
2074
2075
0
    if (ctxt != NULL) {
2076
0
        ctxt->nberrors++;
2077
0
        ctxt->err = XML_ERR_NO_MEMORY;
2078
0
        channel = ctxt->error;
2079
0
        schannel = ctxt->serror;
2080
0
        data = ctxt->errCtxt;
2081
0
    }
2082
2083
0
    xmlRaiseMemoryError(schannel, channel, data, XML_FROM_SCHEMASV, NULL);
2084
0
}
2085
2086
static void LIBXML_ATTR_FORMAT(11,12)
2087
xmlSchemaVErrFull(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr node, int code,
2088
                  xmlErrorLevel level, const char *file, int line,
2089
                  const xmlChar *str1, const xmlChar *str2, const xmlChar *str3,
2090
0
                  int col, const char *msg, ...) {
2091
0
    xmlGenericErrorFunc channel = NULL;
2092
0
    xmlStructuredErrorFunc schannel = NULL;
2093
0
    void *data = NULL;
2094
0
    int res;
2095
0
    va_list ap;
2096
2097
0
    if (ctxt != NULL) {
2098
        /* Don't overwrite memory errors */
2099
0
        if (ctxt->err == XML_ERR_NO_MEMORY)
2100
0
            return;
2101
2102
0
        if (level == XML_ERR_WARNING) {
2103
0
            channel = ctxt->warning;
2104
0
        } else {
2105
0
            ctxt->nberrors++;
2106
0
            ctxt->err = code;
2107
0
            channel = ctxt->error;
2108
0
        }
2109
0
        data = ctxt->errCtxt;
2110
0
        schannel = ctxt->serror;
2111
0
    }
2112
2113
0
    if ((channel == NULL) && (schannel == NULL)) {
2114
0
        channel = xmlGenericError;
2115
0
        data = xmlGenericErrorContext;
2116
0
    }
2117
2118
0
    va_start(ap, msg);
2119
0
    res = xmlVRaiseError(schannel, channel, data, ctxt, node,
2120
0
                         XML_FROM_SCHEMASV, code, level, file, line,
2121
0
                         (const char *) str1,
2122
0
                         (const char *) str2,
2123
0
                         (const char *) str3,
2124
0
                         0, col, msg, ap);
2125
0
    va_end(ap);
2126
2127
0
    if (res < 0)
2128
0
        xmlSchemaVErrMemory(ctxt);
2129
0
}
2130
2131
#define WXS_ERROR_TYPE_ERROR 1
2132
#define WXS_ERROR_TYPE_WARNING 2
2133
/**
2134
 * xmlSchemaErr4Line:
2135
 * @ctxt: the validation context
2136
 * @errorLevel: the error level
2137
 * @error: the error code
2138
 * @node: the context node
2139
 * @line: the line number
2140
 * @msg: the error message
2141
 * @str1: extra data
2142
 * @str2: extra data
2143
 * @str3: extra data
2144
 * @str4: extra data
2145
 *
2146
 * Handle a validation error
2147
 */
2148
static void LIBXML_ATTR_FORMAT(6,0)
2149
xmlSchemaErr4Line(xmlSchemaAbstractCtxtPtr ctxt,
2150
      xmlErrorLevel errorLevel,
2151
      int code, xmlNodePtr node, int line, const char *msg,
2152
      const xmlChar *str1, const xmlChar *str2,
2153
      const xmlChar *str3, const xmlChar *str4)
2154
0
{
2155
0
    if (ctxt != NULL) {
2156
0
  if (ctxt->type == XML_SCHEMA_CTXT_VALIDATOR) {
2157
0
      xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctxt;
2158
0
      const char *file = NULL;
2159
0
      int col = 0;
2160
2161
      /*
2162
      * Error node. If we specify a line number, then
2163
      * do not channel any node to the error function.
2164
      */
2165
0
      if (line == 0) {
2166
0
    if ((node == NULL) &&
2167
0
        (vctxt->depth >= 0) &&
2168
0
        (vctxt->inode != NULL)) {
2169
0
        node = vctxt->inode->node;
2170
0
    }
2171
    /*
2172
    * Get filename and line if no node-tree.
2173
    */
2174
0
    if ((node == NULL) &&
2175
0
        (vctxt->parserCtxt != NULL) &&
2176
0
        (vctxt->parserCtxt->input != NULL)) {
2177
0
        file = vctxt->parserCtxt->input->filename;
2178
0
                    if (vctxt->inode != NULL) {
2179
0
            line = vctxt->inode->nodeLine;
2180
0
                        col = 0;
2181
0
                    } else {
2182
                        /* This is inaccurate. */
2183
0
            line = vctxt->parserCtxt->input->line;
2184
0
            col = vctxt->parserCtxt->input->col;
2185
0
                    }
2186
0
    }
2187
0
      } else {
2188
    /*
2189
    * Override the given node's (if any) position
2190
    * and channel only the given line number.
2191
    */
2192
0
    node = NULL;
2193
    /*
2194
    * Get filename.
2195
    */
2196
0
    if (vctxt->doc != NULL)
2197
0
        file = (const char *) vctxt->doc->URL;
2198
0
    else if ((vctxt->parserCtxt != NULL) &&
2199
0
        (vctxt->parserCtxt->input != NULL))
2200
0
        file = vctxt->parserCtxt->input->filename;
2201
0
      }
2202
0
      if (vctxt->locFunc != NULL) {
2203
0
          if ((file == NULL) || (line == 0)) {
2204
0
        unsigned long l;
2205
0
        const char *f;
2206
0
        vctxt->locFunc(vctxt->locCtxt, &f, &l);
2207
0
        if (file == NULL)
2208
0
            file = f;
2209
0
        if (line == 0)
2210
0
            line = (int) l;
2211
0
    }
2212
0
      }
2213
0
      if ((file == NULL) && (vctxt->filename != NULL))
2214
0
          file = vctxt->filename;
2215
2216
0
            xmlSchemaVErrFull(vctxt, node, code, errorLevel,
2217
0
                              file, line, str1, str2, str3, col,
2218
0
                              msg, str1, str2, str3, str4);
2219
0
  } else if (ctxt->type == XML_SCHEMA_CTXT_PARSER) {
2220
0
      xmlSchemaParserCtxtPtr pctxt = (xmlSchemaParserCtxtPtr) ctxt;
2221
2222
0
            xmlSchemaPErrFull(pctxt, node, code, errorLevel,
2223
0
                              NULL, 0, str1, str2, str3, 0,
2224
0
                              msg, str1, str2, str3, str4);
2225
0
  }
2226
0
    }
2227
0
}
2228
2229
/**
2230
 * xmlSchemaErr3:
2231
 * @ctxt: the validation context
2232
 * @node: the context node
2233
 * @error: the error code
2234
 * @msg: the error message
2235
 * @str1: extra data
2236
 * @str2: extra data
2237
 * @str3: extra data
2238
 *
2239
 * Handle a validation error
2240
 */
2241
static void LIBXML_ATTR_FORMAT(4,0)
2242
xmlSchemaErr3(xmlSchemaAbstractCtxtPtr actxt,
2243
        int error, xmlNodePtr node, const char *msg,
2244
        const xmlChar *str1, const xmlChar *str2, const xmlChar *str3)
2245
0
{
2246
0
    xmlSchemaErr4Line(actxt, XML_ERR_ERROR, error, node, 0,
2247
0
  msg, str1, str2, str3, NULL);
2248
0
}
2249
2250
static void LIBXML_ATTR_FORMAT(4,0)
2251
xmlSchemaErr4(xmlSchemaAbstractCtxtPtr actxt,
2252
        int error, xmlNodePtr node, const char *msg,
2253
        const xmlChar *str1, const xmlChar *str2,
2254
        const xmlChar *str3, const xmlChar *str4)
2255
0
{
2256
0
    xmlSchemaErr4Line(actxt, XML_ERR_ERROR, error, node, 0,
2257
0
  msg, str1, str2, str3, str4);
2258
0
}
2259
2260
static void LIBXML_ATTR_FORMAT(4,0)
2261
xmlSchemaErr(xmlSchemaAbstractCtxtPtr actxt,
2262
       int error, xmlNodePtr node, const char *msg,
2263
       const xmlChar *str1, const xmlChar *str2)
2264
0
{
2265
0
    xmlSchemaErr4(actxt, error, node, msg, str1, str2, NULL, NULL);
2266
0
}
2267
2268
static xmlChar *
2269
xmlSchemaFormatNodeForError(xmlChar ** msg,
2270
          xmlSchemaAbstractCtxtPtr actxt,
2271
          xmlNodePtr node)
2272
0
{
2273
0
    xmlChar *str = NULL;
2274
2275
0
    *msg = NULL;
2276
0
    if ((node != NULL) &&
2277
0
  (node->type != XML_ELEMENT_NODE) &&
2278
0
  (node->type != XML_ATTRIBUTE_NODE))
2279
0
    {
2280
  /*
2281
  * Don't try to format other nodes than element and
2282
  * attribute nodes.
2283
  * Play safe and return an empty string.
2284
  */
2285
0
  *msg = xmlStrdup(BAD_CAST "");
2286
0
  return(*msg);
2287
0
    }
2288
0
    if (node != NULL) {
2289
  /*
2290
  * Work on tree nodes.
2291
  */
2292
0
  if (node->type == XML_ATTRIBUTE_NODE) {
2293
0
      xmlNodePtr elem = node->parent;
2294
2295
0
      *msg = xmlStrdup(BAD_CAST "Element '");
2296
0
      if (elem->ns != NULL)
2297
0
    *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
2298
0
        elem->ns->href, elem->name));
2299
0
      else
2300
0
    *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
2301
0
        NULL, elem->name));
2302
0
      FREE_AND_NULL(str);
2303
0
      *msg = xmlStrcat(*msg, BAD_CAST "', ");
2304
0
      *msg = xmlStrcat(*msg, BAD_CAST "attribute '");
2305
0
  } else {
2306
0
      *msg = xmlStrdup(BAD_CAST "Element '");
2307
0
  }
2308
0
  if (node->ns != NULL)
2309
0
      *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
2310
0
      node->ns->href, node->name));
2311
0
  else
2312
0
      *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
2313
0
      NULL, node->name));
2314
0
  FREE_AND_NULL(str);
2315
0
  *msg = xmlStrcat(*msg, BAD_CAST "': ");
2316
0
    } else if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR) {
2317
0
  xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) actxt;
2318
  /*
2319
  * Work on node infos.
2320
  */
2321
0
  if (vctxt->inode->nodeType == XML_ATTRIBUTE_NODE) {
2322
0
      xmlSchemaNodeInfoPtr ielem =
2323
0
    vctxt->elemInfos[vctxt->depth];
2324
2325
0
      *msg = xmlStrdup(BAD_CAST "Element '");
2326
0
      *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
2327
0
    ielem->nsName, ielem->localName));
2328
0
      FREE_AND_NULL(str);
2329
0
      *msg = xmlStrcat(*msg, BAD_CAST "', ");
2330
0
      *msg = xmlStrcat(*msg, BAD_CAST "attribute '");
2331
0
  } else {
2332
0
      *msg = xmlStrdup(BAD_CAST "Element '");
2333
0
  }
2334
0
  *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
2335
0
      vctxt->inode->nsName, vctxt->inode->localName));
2336
0
  FREE_AND_NULL(str);
2337
0
  *msg = xmlStrcat(*msg, BAD_CAST "': ");
2338
0
    } else if (actxt->type == XML_SCHEMA_CTXT_PARSER) {
2339
  /*
2340
  * Hmm, no node while parsing?
2341
  * Return an empty string, in case NULL will break something.
2342
  */
2343
0
  *msg = xmlStrdup(BAD_CAST "");
2344
0
    } else {
2345
  /* TODO */
2346
0
  return (NULL);
2347
0
    }
2348
2349
    /*
2350
     * xmlSchemaFormatItemForReport() also returns an escaped format
2351
     * string, so do this before calling it below (in the future).
2352
     */
2353
0
    xmlEscapeFormatString(msg);
2354
2355
    /*
2356
    * VAL TODO: The output of the given schema component is currently
2357
    * disabled.
2358
    */
2359
#if 0
2360
    if ((type != NULL) && (xmlSchemaIsGlobalItem(type))) {
2361
  *msg = xmlStrcat(*msg, BAD_CAST " [");
2362
  *msg = xmlStrcat(*msg, xmlSchemaFormatItemForReport(&str,
2363
      NULL, type, NULL, 0));
2364
  FREE_AND_NULL(str)
2365
  *msg = xmlStrcat(*msg, BAD_CAST "]");
2366
    }
2367
#endif
2368
0
    return (*msg);
2369
0
}
2370
2371
static void LIBXML_ATTR_FORMAT(3,0)
2372
xmlSchemaInternalErr2(xmlSchemaAbstractCtxtPtr actxt,
2373
         const char *funcName,
2374
         const char *message,
2375
         const xmlChar *str1,
2376
         const xmlChar *str2)
2377
0
{
2378
0
    xmlChar *msg = NULL;
2379
2380
0
    if (actxt == NULL)
2381
0
        return;
2382
0
    msg = xmlStrdup(BAD_CAST "Internal error: %s, ");
2383
0
    msg = xmlStrcat(msg, BAD_CAST message);
2384
0
    msg = xmlStrcat(msg, BAD_CAST ".\n");
2385
2386
0
    if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR)
2387
0
  xmlSchemaErr3(actxt, XML_SCHEMAV_INTERNAL, NULL,
2388
0
      (const char *) msg, (const xmlChar *) funcName, str1, str2);
2389
0
    else if (actxt->type == XML_SCHEMA_CTXT_PARSER)
2390
0
  xmlSchemaErr3(actxt, XML_SCHEMAP_INTERNAL, NULL,
2391
0
      (const char *) msg, (const xmlChar *) funcName, str1, str2);
2392
2393
0
    FREE_AND_NULL(msg)
2394
0
}
2395
2396
static void LIBXML_ATTR_FORMAT(3,0)
2397
xmlSchemaInternalErr(xmlSchemaAbstractCtxtPtr actxt,
2398
         const char *funcName,
2399
         const char *message)
2400
0
{
2401
0
    xmlSchemaInternalErr2(actxt, funcName, message, NULL, NULL);
2402
0
}
2403
2404
#if 0
2405
static void LIBXML_ATTR_FORMAT(3,0)
2406
xmlSchemaPInternalErr(xmlSchemaParserCtxtPtr pctxt,
2407
         const char *funcName,
2408
         const char *message,
2409
         const xmlChar *str1,
2410
         const xmlChar *str2)
2411
{
2412
    xmlSchemaInternalErr2(ACTXT_CAST pctxt, funcName, message,
2413
  str1, str2);
2414
}
2415
#endif
2416
2417
static void LIBXML_ATTR_FORMAT(5,0)
2418
xmlSchemaCustomErr4(xmlSchemaAbstractCtxtPtr actxt,
2419
       xmlParserErrors error,
2420
       xmlNodePtr node,
2421
       xmlSchemaBasicItemPtr item,
2422
       const char *message,
2423
       const xmlChar *str1, const xmlChar *str2,
2424
       const xmlChar *str3, const xmlChar *str4)
2425
0
{
2426
0
    xmlChar *msg = NULL;
2427
2428
0
    if ((node == NULL) && (item != NULL) &&
2429
0
  (actxt->type == XML_SCHEMA_CTXT_PARSER)) {
2430
0
  node = WXS_ITEM_NODE(item);
2431
0
  xmlSchemaFormatItemForReport(&msg, NULL, item, NULL);
2432
0
  msg = xmlStrcat(msg, BAD_CAST ": ");
2433
0
    } else
2434
0
  xmlSchemaFormatNodeForError(&msg, actxt, node);
2435
0
    msg = xmlStrcat(msg, (const xmlChar *) message);
2436
0
    msg = xmlStrcat(msg, BAD_CAST ".\n");
2437
0
    xmlSchemaErr4(actxt, error, node,
2438
0
  (const char *) msg, str1, str2, str3, str4);
2439
0
    FREE_AND_NULL(msg)
2440
0
}
2441
2442
static void LIBXML_ATTR_FORMAT(5,0)
2443
xmlSchemaCustomErr(xmlSchemaAbstractCtxtPtr actxt,
2444
       xmlParserErrors error,
2445
       xmlNodePtr node,
2446
       xmlSchemaBasicItemPtr item,
2447
       const char *message,
2448
       const xmlChar *str1,
2449
       const xmlChar *str2)
2450
0
{
2451
0
    xmlSchemaCustomErr4(actxt, error, node, item,
2452
0
  message, str1, str2, NULL, NULL);
2453
0
}
2454
2455
2456
2457
static void LIBXML_ATTR_FORMAT(5,0)
2458
xmlSchemaCustomWarning(xmlSchemaAbstractCtxtPtr actxt,
2459
       xmlParserErrors error,
2460
       xmlNodePtr node,
2461
       xmlSchemaTypePtr type ATTRIBUTE_UNUSED,
2462
       const char *message,
2463
       const xmlChar *str1,
2464
       const xmlChar *str2,
2465
       const xmlChar *str3)
2466
0
{
2467
0
    xmlChar *msg = NULL;
2468
2469
0
    xmlSchemaFormatNodeForError(&msg, actxt, node);
2470
0
    msg = xmlStrcat(msg, (const xmlChar *) message);
2471
0
    msg = xmlStrcat(msg, BAD_CAST ".\n");
2472
2473
    /* URGENT TODO: Set the error code to something sane. */
2474
0
    xmlSchemaErr4Line(actxt, XML_ERR_WARNING, error, node, 0,
2475
0
  (const char *) msg, str1, str2, str3, NULL);
2476
2477
0
    FREE_AND_NULL(msg)
2478
0
}
2479
2480
2481
2482
static void LIBXML_ATTR_FORMAT(5,0)
2483
xmlSchemaKeyrefErr(xmlSchemaValidCtxtPtr vctxt,
2484
       xmlParserErrors error,
2485
       xmlSchemaPSVIIDCNodePtr idcNode,
2486
       xmlSchemaTypePtr type ATTRIBUTE_UNUSED,
2487
       const char *message,
2488
       const xmlChar *str1,
2489
       const xmlChar *str2)
2490
0
{
2491
0
    xmlChar *msg = NULL, *qname = NULL;
2492
2493
0
    msg = xmlStrdup(BAD_CAST "Element '%s': ");
2494
0
    msg = xmlStrcat(msg, (const xmlChar *) message);
2495
0
    msg = xmlStrcat(msg, BAD_CAST ".\n");
2496
0
    xmlSchemaErr4Line(ACTXT_CAST vctxt, XML_ERR_ERROR,
2497
0
  error, NULL, idcNode->nodeLine, (const char *) msg,
2498
0
  xmlSchemaFormatQName(&qname,
2499
0
      vctxt->nodeQNames->items[idcNode->nodeQNameID +1],
2500
0
      vctxt->nodeQNames->items[idcNode->nodeQNameID]),
2501
0
  str1, str2, NULL);
2502
0
    FREE_AND_NULL(qname);
2503
0
    FREE_AND_NULL(msg);
2504
0
}
2505
2506
static int
2507
xmlSchemaEvalErrorNodeType(xmlSchemaAbstractCtxtPtr actxt,
2508
         xmlNodePtr node)
2509
0
{
2510
0
    if (node != NULL)
2511
0
  return (node->type);
2512
0
    if ((actxt->type == XML_SCHEMA_CTXT_VALIDATOR) &&
2513
0
  (((xmlSchemaValidCtxtPtr) actxt)->inode != NULL))
2514
0
  return ( ((xmlSchemaValidCtxtPtr) actxt)->inode->nodeType);
2515
0
    return (-1);
2516
0
}
2517
2518
static int
2519
xmlSchemaIsGlobalItem(xmlSchemaTypePtr item)
2520
0
{
2521
0
    switch (item->type) {
2522
0
  case XML_SCHEMA_TYPE_COMPLEX:
2523
0
  case XML_SCHEMA_TYPE_SIMPLE:
2524
0
      if (item->flags & XML_SCHEMAS_TYPE_GLOBAL)
2525
0
    return(1);
2526
0
      break;
2527
0
  case XML_SCHEMA_TYPE_GROUP:
2528
0
      return (1);
2529
0
  case XML_SCHEMA_TYPE_ELEMENT:
2530
0
      if ( ((xmlSchemaElementPtr) item)->flags &
2531
0
    XML_SCHEMAS_ELEM_GLOBAL)
2532
0
    return(1);
2533
0
      break;
2534
0
  case XML_SCHEMA_TYPE_ATTRIBUTE:
2535
0
      if ( ((xmlSchemaAttributePtr) item)->flags &
2536
0
    XML_SCHEMAS_ATTR_GLOBAL)
2537
0
    return(1);
2538
0
      break;
2539
  /* Note that attribute groups are always global. */
2540
0
  default:
2541
0
      return(1);
2542
0
    }
2543
0
    return (0);
2544
0
}
2545
2546
static void
2547
xmlSchemaSimpleTypeErr(xmlSchemaAbstractCtxtPtr actxt,
2548
           xmlParserErrors error,
2549
           xmlNodePtr node,
2550
           const xmlChar *value,
2551
           xmlSchemaTypePtr type,
2552
           int displayValue)
2553
0
{
2554
0
    xmlChar *msg = NULL;
2555
2556
0
    xmlSchemaFormatNodeForError(&msg, actxt, node);
2557
2558
0
    if (displayValue || (xmlSchemaEvalErrorNodeType(actxt, node) ==
2559
0
      XML_ATTRIBUTE_NODE))
2560
0
  msg = xmlStrcat(msg, BAD_CAST "'%s' is not a valid value of ");
2561
0
    else
2562
0
  msg = xmlStrcat(msg, BAD_CAST "The character content is not a valid "
2563
0
      "value of ");
2564
2565
0
    if (! xmlSchemaIsGlobalItem(type))
2566
0
  msg = xmlStrcat(msg, BAD_CAST "the local ");
2567
0
    else
2568
0
  msg = xmlStrcat(msg, BAD_CAST "the ");
2569
2570
0
    if (WXS_IS_ATOMIC(type))
2571
0
  msg = xmlStrcat(msg, BAD_CAST "atomic type");
2572
0
    else if (WXS_IS_LIST(type))
2573
0
  msg = xmlStrcat(msg, BAD_CAST "list type");
2574
0
    else if (WXS_IS_UNION(type))
2575
0
  msg = xmlStrcat(msg, BAD_CAST "union type");
2576
2577
0
    if (xmlSchemaIsGlobalItem(type)) {
2578
0
  xmlChar *str = NULL;
2579
0
  msg = xmlStrcat(msg, BAD_CAST " '");
2580
0
  if (type->builtInType != 0) {
2581
0
      msg = xmlStrcat(msg, BAD_CAST "xs:");
2582
0
      str = xmlStrdup(type->name);
2583
0
  } else {
2584
0
      const xmlChar *qName = xmlSchemaFormatQName(&str, type->targetNamespace, type->name);
2585
0
      if (!str)
2586
0
    str = xmlStrdup(qName);
2587
0
  }
2588
0
  msg = xmlStrcat(msg, xmlEscapeFormatString(&str));
2589
0
  msg = xmlStrcat(msg, BAD_CAST "'");
2590
0
  FREE_AND_NULL(str);
2591
0
    }
2592
0
    msg = xmlStrcat(msg, BAD_CAST ".\n");
2593
0
    if (displayValue || (xmlSchemaEvalErrorNodeType(actxt, node) ==
2594
0
      XML_ATTRIBUTE_NODE))
2595
0
  xmlSchemaErr(actxt, error, node, (const char *) msg, value, NULL);
2596
0
    else
2597
0
  xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL);
2598
0
    FREE_AND_NULL(msg)
2599
0
}
2600
2601
static const xmlChar *
2602
xmlSchemaFormatErrorNodeQName(xmlChar ** str,
2603
            xmlSchemaNodeInfoPtr ni,
2604
            xmlNodePtr node)
2605
0
{
2606
0
    if (node != NULL) {
2607
0
  if (node->ns != NULL)
2608
0
      return (xmlSchemaFormatQName(str, node->ns->href, node->name));
2609
0
  else
2610
0
      return (xmlSchemaFormatQName(str, NULL, node->name));
2611
0
    } else if (ni != NULL)
2612
0
  return (xmlSchemaFormatQName(str, ni->nsName, ni->localName));
2613
0
    return (NULL);
2614
0
}
2615
2616
static void
2617
xmlSchemaIllegalAttrErr(xmlSchemaAbstractCtxtPtr actxt,
2618
      xmlParserErrors error,
2619
      xmlSchemaAttrInfoPtr ni,
2620
      xmlNodePtr node)
2621
0
{
2622
0
    xmlChar *msg = NULL, *str = NULL;
2623
2624
0
    xmlSchemaFormatNodeForError(&msg, actxt, node);
2625
0
    msg = xmlStrcat(msg, BAD_CAST "The attribute '%s' is not allowed.\n");
2626
0
    xmlSchemaErr(actxt, error, node, (const char *) msg,
2627
0
  xmlSchemaFormatErrorNodeQName(&str, (xmlSchemaNodeInfoPtr) ni, node),
2628
0
  NULL);
2629
0
    FREE_AND_NULL(str)
2630
0
    FREE_AND_NULL(msg)
2631
0
}
2632
2633
static void LIBXML_ATTR_FORMAT(5,0)
2634
xmlSchemaComplexTypeErr(xmlSchemaAbstractCtxtPtr actxt,
2635
            xmlParserErrors error,
2636
            xmlNodePtr node,
2637
      xmlSchemaTypePtr type ATTRIBUTE_UNUSED,
2638
      const char *message,
2639
      int nbval,
2640
      int nbneg,
2641
      xmlChar **values)
2642
0
{
2643
0
    xmlChar *str = NULL, *msg = NULL;
2644
0
    xmlChar *localName, *nsName;
2645
0
    const xmlChar *cur, *end;
2646
0
    int i;
2647
2648
0
    xmlSchemaFormatNodeForError(&msg, actxt, node);
2649
0
    msg = xmlStrcat(msg, (const xmlChar *) message);
2650
0
    msg = xmlStrcat(msg, BAD_CAST ".");
2651
    /*
2652
    * Note that is does not make sense to report that we have a
2653
    * wildcard here, since the wildcard might be unfolded into
2654
    * multiple transitions.
2655
    */
2656
0
    if (nbval + nbneg > 0) {
2657
0
  if (nbval + nbneg > 1) {
2658
0
      str = xmlStrdup(BAD_CAST " Expected is one of ( ");
2659
0
  } else
2660
0
      str = xmlStrdup(BAD_CAST " Expected is ( ");
2661
0
  nsName = NULL;
2662
2663
0
  for (i = 0; i < nbval + nbneg; i++) {
2664
0
      cur = values[i];
2665
0
      if (cur == NULL)
2666
0
          continue;
2667
0
      if ((cur[0] == 'n') && (cur[1] == 'o') && (cur[2] == 't') &&
2668
0
          (cur[3] == ' ')) {
2669
0
    cur += 4;
2670
0
    str = xmlStrcat(str, BAD_CAST "##other");
2671
0
      }
2672
      /*
2673
      * Get the local name.
2674
      */
2675
0
      localName = NULL;
2676
2677
0
      end = cur;
2678
0
      if (*end == '*') {
2679
0
    localName = xmlStrdup(BAD_CAST "*");
2680
0
    end++;
2681
0
      } else {
2682
0
    while ((*end != 0) && (*end != '|'))
2683
0
        end++;
2684
0
    localName = xmlStrncat(localName, BAD_CAST cur, end - cur);
2685
0
      }
2686
0
      if (*end != 0) {
2687
0
    end++;
2688
    /*
2689
    * Skip "*|*" if they come with negated expressions, since
2690
    * they represent the same negated wildcard.
2691
    */
2692
0
    if ((nbneg == 0) || (*end != '*') || (*localName != '*')) {
2693
        /*
2694
        * Get the namespace name.
2695
        */
2696
0
        cur = end;
2697
0
        if (*end == '*') {
2698
0
      nsName = xmlStrdup(BAD_CAST "{*}");
2699
0
        } else {
2700
0
      while (*end != 0)
2701
0
          end++;
2702
2703
0
      if (i >= nbval)
2704
0
          nsName = xmlStrdup(BAD_CAST "{##other:");
2705
0
      else
2706
0
          nsName = xmlStrdup(BAD_CAST "{");
2707
2708
0
      nsName = xmlStrncat(nsName, BAD_CAST cur, end - cur);
2709
0
      nsName = xmlStrcat(nsName, BAD_CAST "}");
2710
0
        }
2711
0
        str = xmlStrcat(str, BAD_CAST nsName);
2712
0
        FREE_AND_NULL(nsName)
2713
0
    } else {
2714
0
        FREE_AND_NULL(localName);
2715
0
        continue;
2716
0
    }
2717
0
      }
2718
0
      str = xmlStrcat(str, BAD_CAST localName);
2719
0
      FREE_AND_NULL(localName);
2720
2721
0
      if (i < nbval + nbneg -1)
2722
0
    str = xmlStrcat(str, BAD_CAST ", ");
2723
0
  }
2724
0
  str = xmlStrcat(str, BAD_CAST " ).\n");
2725
0
  msg = xmlStrcat(msg, xmlEscapeFormatString(&str));
2726
0
  FREE_AND_NULL(str)
2727
0
    } else
2728
0
      msg = xmlStrcat(msg, BAD_CAST "\n");
2729
0
    xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL);
2730
0
    xmlFree(msg);
2731
0
}
2732
2733
static void LIBXML_ATTR_FORMAT(8,0)
2734
xmlSchemaFacetErr(xmlSchemaAbstractCtxtPtr actxt,
2735
      xmlParserErrors error,
2736
      xmlNodePtr node,
2737
      const xmlChar *value,
2738
      unsigned long length,
2739
      xmlSchemaTypePtr type,
2740
      xmlSchemaFacetPtr facet,
2741
      const char *message,
2742
      const xmlChar *str1,
2743
      const xmlChar *str2)
2744
0
{
2745
0
    xmlChar *str = NULL, *msg = NULL;
2746
0
    xmlSchemaTypeType facetType;
2747
0
    int nodeType = xmlSchemaEvalErrorNodeType(actxt, node);
2748
2749
0
    xmlSchemaFormatNodeForError(&msg, actxt, node);
2750
0
    if (error == XML_SCHEMAV_CVC_ENUMERATION_VALID) {
2751
0
  facetType = XML_SCHEMA_FACET_ENUMERATION;
2752
  /*
2753
  * If enumerations are validated, one must not expect the
2754
  * facet to be given.
2755
  */
2756
0
    } else
2757
0
  facetType = facet->type;
2758
0
    msg = xmlStrcat(msg, BAD_CAST "[");
2759
0
    msg = xmlStrcat(msg, BAD_CAST "facet '");
2760
0
    msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facetType));
2761
0
    msg = xmlStrcat(msg, BAD_CAST "'] ");
2762
0
    if (message == NULL) {
2763
  /*
2764
  * Use a default message.
2765
  */
2766
0
  if ((facetType == XML_SCHEMA_FACET_LENGTH) ||
2767
0
      (facetType == XML_SCHEMA_FACET_MINLENGTH) ||
2768
0
      (facetType == XML_SCHEMA_FACET_MAXLENGTH)) {
2769
2770
0
      char len[25], actLen[25];
2771
2772
      /* FIXME, TODO: What is the max expected string length of the
2773
      * this value?
2774
      */
2775
0
      if (nodeType == XML_ATTRIBUTE_NODE)
2776
0
    msg = xmlStrcat(msg, BAD_CAST "The value '%s' has a length of '%s'; ");
2777
0
      else
2778
0
    msg = xmlStrcat(msg, BAD_CAST "The value has a length of '%s'; ");
2779
2780
0
      snprintf(len, 24, "%lu", xmlSchemaGetFacetValueAsULong(facet));
2781
0
      snprintf(actLen, 24, "%lu", length);
2782
2783
0
      if (facetType == XML_SCHEMA_FACET_LENGTH)
2784
0
    msg = xmlStrcat(msg,
2785
0
    BAD_CAST "this differs from the allowed length of '%s'.\n");
2786
0
      else if (facetType == XML_SCHEMA_FACET_MAXLENGTH)
2787
0
    msg = xmlStrcat(msg,
2788
0
    BAD_CAST "this exceeds the allowed maximum length of '%s'.\n");
2789
0
      else if (facetType == XML_SCHEMA_FACET_MINLENGTH)
2790
0
    msg = xmlStrcat(msg,
2791
0
    BAD_CAST "this underruns the allowed minimum length of '%s'.\n");
2792
2793
0
      if (nodeType == XML_ATTRIBUTE_NODE)
2794
0
    xmlSchemaErr3(actxt, error, node, (const char *) msg,
2795
0
        value, (const xmlChar *) actLen, (const xmlChar *) len);
2796
0
      else
2797
0
    xmlSchemaErr(actxt, error, node, (const char *) msg,
2798
0
        (const xmlChar *) actLen, (const xmlChar *) len);
2799
2800
0
  } else if (facetType == XML_SCHEMA_FACET_ENUMERATION) {
2801
0
      msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not an element "
2802
0
    "of the set {%s}.\n");
2803
0
      xmlSchemaErr(actxt, error, node, (const char *) msg, value,
2804
0
    xmlSchemaFormatFacetEnumSet(actxt, &str, type));
2805
0
  } else if (facetType == XML_SCHEMA_FACET_PATTERN) {
2806
0
      msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not accepted "
2807
0
    "by the pattern '%s'.\n");
2808
0
      xmlSchemaErr(actxt, error, node, (const char *) msg, value,
2809
0
    facet->value);
2810
0
  } else if (facetType == XML_SCHEMA_FACET_MININCLUSIVE) {
2811
0
      msg = xmlStrcat(msg, BAD_CAST "The value '%s' is less than the "
2812
0
    "minimum value allowed ('%s').\n");
2813
0
      xmlSchemaErr(actxt, error, node, (const char *) msg, value,
2814
0
    facet->value);
2815
0
  } else if (facetType == XML_SCHEMA_FACET_MAXINCLUSIVE) {
2816
0
      msg = xmlStrcat(msg, BAD_CAST "The value '%s' is greater than the "
2817
0
    "maximum value allowed ('%s').\n");
2818
0
      xmlSchemaErr(actxt, error, node, (const char *) msg, value,
2819
0
    facet->value);
2820
0
  } else if (facetType == XML_SCHEMA_FACET_MINEXCLUSIVE) {
2821
0
      msg = xmlStrcat(msg, BAD_CAST "The value '%s' must be greater than "
2822
0
    "'%s'.\n");
2823
0
      xmlSchemaErr(actxt, error, node, (const char *) msg, value,
2824
0
    facet->value);
2825
0
  } else if (facetType == XML_SCHEMA_FACET_MAXEXCLUSIVE) {
2826
0
      msg = xmlStrcat(msg, BAD_CAST "The value '%s' must be less than "
2827
0
    "'%s'.\n");
2828
0
      xmlSchemaErr(actxt, error, node, (const char *) msg, value,
2829
0
    facet->value);
2830
0
  } else if (facetType == XML_SCHEMA_FACET_TOTALDIGITS) {
2831
0
      msg = xmlStrcat(msg, BAD_CAST "The value '%s' has more "
2832
0
    "digits than are allowed ('%s').\n");
2833
0
      xmlSchemaErr(actxt, error, node, (const char*) msg, value,
2834
0
    facet->value);
2835
0
  } else if (facetType == XML_SCHEMA_FACET_FRACTIONDIGITS) {
2836
0
      msg = xmlStrcat(msg, BAD_CAST "The value '%s' has more fractional "
2837
0
    "digits than are allowed ('%s').\n");
2838
0
      xmlSchemaErr(actxt, error, node, (const char*) msg, value,
2839
0
    facet->value);
2840
0
  } else if (nodeType == XML_ATTRIBUTE_NODE) {
2841
0
      msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not facet-valid.\n");
2842
0
      xmlSchemaErr(actxt, error, node, (const char *) msg, value, NULL);
2843
0
  } else {
2844
0
      msg = xmlStrcat(msg, BAD_CAST "The value is not facet-valid.\n");
2845
0
      xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL);
2846
0
  }
2847
0
    } else {
2848
0
  msg = xmlStrcat(msg, (const xmlChar *) message);
2849
0
  msg = xmlStrcat(msg, BAD_CAST ".\n");
2850
0
  xmlSchemaErr(actxt, error, node, (const char *) msg, str1, str2);
2851
0
    }
2852
0
    FREE_AND_NULL(str)
2853
0
    xmlFree(msg);
2854
0
}
2855
2856
#define VERROR(err, type, msg) \
2857
0
    xmlSchemaCustomErr(ACTXT_CAST vctxt, err, NULL, type, msg, NULL, NULL);
2858
2859
0
#define VERROR_INT(func, msg) xmlSchemaInternalErr(ACTXT_CAST vctxt, func, msg);
2860
2861
0
#define PERROR_INT(func, msg) xmlSchemaInternalErr(ACTXT_CAST pctxt, func, msg);
2862
0
#define PERROR_INT2(func, msg) xmlSchemaInternalErr(ACTXT_CAST ctxt, func, msg);
2863
2864
0
#define AERROR_INT(func, msg) xmlSchemaInternalErr(actxt, func, msg);
2865
2866
2867
/**
2868
 * xmlSchemaPMissingAttrErr:
2869
 * @ctxt: the schema validation context
2870
 * @ownerItem: the owner as a schema object
2871
 * @ownerElem: the owner as an element node
2872
 * @node: the parent element node of the missing attribute node
2873
 * @type: the corresponding type of the attribute node
2874
 *
2875
 * Reports an illegal attribute.
2876
 */
2877
static void
2878
xmlSchemaPMissingAttrErr(xmlSchemaParserCtxtPtr ctxt,
2879
       xmlParserErrors error,
2880
       xmlSchemaBasicItemPtr ownerItem,
2881
       xmlNodePtr ownerElem,
2882
       const char *name,
2883
       const char *message)
2884
0
{
2885
0
    xmlChar *des = NULL;
2886
2887
0
    xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem);
2888
2889
0
    if (message != NULL)
2890
0
  xmlSchemaPErr(ctxt, ownerElem, error, "%s: %s.\n", BAD_CAST des, BAD_CAST message);
2891
0
    else
2892
0
  xmlSchemaPErr(ctxt, ownerElem, error,
2893
0
      "%s: The attribute '%s' is required but missing.\n",
2894
0
      BAD_CAST des, BAD_CAST name);
2895
0
    FREE_AND_NULL(des);
2896
0
}
2897
2898
2899
/**
2900
 * xmlSchemaPResCompAttrErr:
2901
 * @ctxt: the schema validation context
2902
 * @error: the error code
2903
 * @ownerItem: the owner as a schema object
2904
 * @ownerElem: the owner as an element node
2905
 * @name: the name of the attribute holding the QName
2906
 * @refName: the referenced local name
2907
 * @refURI: the referenced namespace URI
2908
 * @message: optional message
2909
 *
2910
 * Used to report QName attribute values that failed to resolve
2911
 * to schema components.
2912
 */
2913
static void
2914
xmlSchemaPResCompAttrErr(xmlSchemaParserCtxtPtr ctxt,
2915
       xmlParserErrors error,
2916
       xmlSchemaBasicItemPtr ownerItem,
2917
       xmlNodePtr ownerElem,
2918
       const char *name,
2919
       const xmlChar *refName,
2920
       const xmlChar *refURI,
2921
       xmlSchemaTypeType refType,
2922
       const char *refTypeStr)
2923
0
{
2924
0
    xmlChar *des = NULL, *strA = NULL;
2925
2926
0
    xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem);
2927
0
    if (refTypeStr == NULL)
2928
0
  refTypeStr = (const char *) xmlSchemaItemTypeToStr(refType);
2929
0
    xmlSchemaPErrExt(ctxt, ownerElem, error,
2930
0
      NULL, NULL, NULL,
2931
0
      "%s, attribute '%s': The QName value '%s' does not resolve to a(n) "
2932
0
      "%s.\n", BAD_CAST des, BAD_CAST name,
2933
0
      xmlSchemaFormatQName(&strA, refURI, refName),
2934
0
      BAD_CAST refTypeStr, NULL);
2935
0
    FREE_AND_NULL(des)
2936
0
    FREE_AND_NULL(strA)
2937
0
}
2938
2939
/**
2940
 * xmlSchemaPCustomAttrErr:
2941
 * @ctxt: the schema parser context
2942
 * @error: the error code
2943
 * @ownerDes: the designation of the owner
2944
 * @ownerItem: the owner as a schema object
2945
 * @attr: the illegal attribute node
2946
 *
2947
 * Reports an illegal attribute during the parse.
2948
 */
2949
static void
2950
xmlSchemaPCustomAttrErr(xmlSchemaParserCtxtPtr ctxt,
2951
      xmlParserErrors error,
2952
      xmlChar **ownerDes,
2953
      xmlSchemaBasicItemPtr ownerItem,
2954
      xmlAttrPtr attr,
2955
      const char *msg)
2956
0
{
2957
0
    xmlChar *des = NULL;
2958
2959
0
    if (ownerDes == NULL)
2960
0
  xmlSchemaFormatItemForReport(&des, NULL, ownerItem, attr->parent);
2961
0
    else if (*ownerDes == NULL) {
2962
0
  xmlSchemaFormatItemForReport(ownerDes, NULL, ownerItem, attr->parent);
2963
0
  des = *ownerDes;
2964
0
    } else
2965
0
  des = *ownerDes;
2966
0
    if (attr == NULL) {
2967
0
  xmlSchemaPErrExt(ctxt, NULL, error, NULL, NULL, NULL,
2968
0
      "%s, attribute '%s': %s.\n",
2969
0
      BAD_CAST des, (const xmlChar *) "Unknown",
2970
0
      (const xmlChar *) msg, NULL, NULL);
2971
0
    } else {
2972
0
  xmlSchemaPErrExt(ctxt, (xmlNodePtr) attr, error, NULL, NULL, NULL,
2973
0
      "%s, attribute '%s': %s.\n",
2974
0
      BAD_CAST des, attr->name, (const xmlChar *) msg, NULL, NULL);
2975
0
    }
2976
0
    if (ownerDes == NULL)
2977
0
  FREE_AND_NULL(des);
2978
0
}
2979
2980
/**
2981
 * xmlSchemaPIllegalAttrErr:
2982
 * @ctxt: the schema parser context
2983
 * @error: the error code
2984
 * @ownerItem: the attribute's owner item
2985
 * @attr: the illegal attribute node
2986
 *
2987
 * Reports an illegal attribute during the parse.
2988
 */
2989
static void
2990
xmlSchemaPIllegalAttrErr(xmlSchemaParserCtxtPtr ctxt,
2991
       xmlParserErrors error,
2992
       xmlSchemaBasicItemPtr ownerComp ATTRIBUTE_UNUSED,
2993
       xmlAttrPtr attr)
2994
0
{
2995
0
    xmlChar *strA = NULL, *strB = NULL;
2996
2997
0
    xmlSchemaFormatNodeForError(&strA, ACTXT_CAST ctxt, attr->parent);
2998
0
    xmlSchemaErr4(ACTXT_CAST ctxt, error, (xmlNodePtr) attr,
2999
0
  "%sThe attribute '%s' is not allowed.\n", BAD_CAST strA,
3000
0
  xmlSchemaFormatQNameNs(&strB, attr->ns, attr->name),
3001
0
  NULL, NULL);
3002
0
    FREE_AND_NULL(strA);
3003
0
    FREE_AND_NULL(strB);
3004
0
}
3005
3006
/**
3007
 * xmlSchemaPCustomErr:
3008
 * @ctxt: the schema parser context
3009
 * @error: the error code
3010
 * @itemDes: the designation of the schema item
3011
 * @item: the schema item
3012
 * @itemElem: the node of the schema item
3013
 * @message: the error message
3014
 * @str1: an optional param for the error message
3015
 * @str2: an optional param for the error message
3016
 * @str3: an optional param for the error message
3017
 *
3018
 * Reports an error during parsing.
3019
 */
3020
static void LIBXML_ATTR_FORMAT(5,0)
3021
xmlSchemaPCustomErrExt(xmlSchemaParserCtxtPtr ctxt,
3022
        xmlParserErrors error,
3023
        xmlSchemaBasicItemPtr item,
3024
        xmlNodePtr itemElem,
3025
        const char *message,
3026
        const xmlChar *str1,
3027
        const xmlChar *str2,
3028
        const xmlChar *str3)
3029
0
{
3030
0
    xmlChar *des = NULL, *msg = NULL;
3031
3032
0
    xmlSchemaFormatItemForReport(&des, NULL, item, itemElem);
3033
0
    msg = xmlStrdup(BAD_CAST "%s: ");
3034
0
    msg = xmlStrcat(msg, (const xmlChar *) message);
3035
0
    msg = xmlStrcat(msg, BAD_CAST ".\n");
3036
0
    if ((itemElem == NULL) && (item != NULL))
3037
0
  itemElem = WXS_ITEM_NODE(item);
3038
0
    xmlSchemaPErrExt(ctxt, itemElem, error, NULL, NULL, NULL,
3039
0
  (const char *) msg, BAD_CAST des, str1, str2, str3, NULL);
3040
0
    FREE_AND_NULL(des);
3041
0
    FREE_AND_NULL(msg);
3042
0
}
3043
3044
/**
3045
 * xmlSchemaPCustomErr:
3046
 * @ctxt: the schema parser context
3047
 * @error: the error code
3048
 * @itemDes: the designation of the schema item
3049
 * @item: the schema item
3050
 * @itemElem: the node of the schema item
3051
 * @message: the error message
3052
 * @str1: the optional param for the error message
3053
 *
3054
 * Reports an error during parsing.
3055
 */
3056
static void LIBXML_ATTR_FORMAT(5,0)
3057
xmlSchemaPCustomErr(xmlSchemaParserCtxtPtr ctxt,
3058
        xmlParserErrors error,
3059
        xmlSchemaBasicItemPtr item,
3060
        xmlNodePtr itemElem,
3061
        const char *message,
3062
        const xmlChar *str1)
3063
0
{
3064
0
    xmlSchemaPCustomErrExt(ctxt, error, item, itemElem, message,
3065
0
  str1, NULL, NULL);
3066
0
}
3067
3068
/**
3069
 * xmlSchemaPAttrUseErr:
3070
 * @ctxt: the schema parser context
3071
 * @error: the error code
3072
 * @itemDes: the designation of the schema type
3073
 * @item: the schema type
3074
 * @itemElem: the node of the schema type
3075
 * @attr: the invalid schema attribute
3076
 * @message: the error message
3077
 * @str1: the optional param for the error message
3078
 *
3079
 * Reports an attribute use error during parsing.
3080
 */
3081
static void LIBXML_ATTR_FORMAT(6,0)
3082
xmlSchemaPAttrUseErr4(xmlSchemaParserCtxtPtr ctxt,
3083
        xmlParserErrors error,
3084
        xmlNodePtr node,
3085
        xmlSchemaBasicItemPtr ownerItem,
3086
        const xmlSchemaAttributeUsePtr attruse,
3087
        const char *message,
3088
        const xmlChar *str1, const xmlChar *str2,
3089
        const xmlChar *str3,const xmlChar *str4)
3090
0
{
3091
0
    xmlChar *str = NULL, *msg = NULL;
3092
3093
0
    xmlSchemaFormatItemForReport(&msg, NULL, ownerItem, NULL);
3094
0
    msg = xmlStrcat(msg, BAD_CAST ", ");
3095
0
    msg = xmlStrcat(msg,
3096
0
  BAD_CAST xmlSchemaFormatItemForReport(&str, NULL,
3097
0
  WXS_BASIC_CAST attruse, NULL));
3098
0
    FREE_AND_NULL(str);
3099
0
    msg = xmlStrcat(msg, BAD_CAST ": ");
3100
0
    msg = xmlStrcat(msg, (const xmlChar *) message);
3101
0
    msg = xmlStrcat(msg, BAD_CAST ".\n");
3102
0
    xmlSchemaErr4(ACTXT_CAST ctxt, error, node,
3103
0
  (const char *) msg, str1, str2, str3, str4);
3104
0
    xmlFree(msg);
3105
0
}
3106
3107
/**
3108
 * xmlSchemaPIllegalFacetAtomicErr:
3109
 * @ctxt: the schema parser context
3110
 * @error: the error code
3111
 * @type: the schema type
3112
 * @baseType: the base type of type
3113
 * @facet: the illegal facet
3114
 *
3115
 * Reports an illegal facet for atomic simple types.
3116
 */
3117
static void
3118
xmlSchemaPIllegalFacetAtomicErr(xmlSchemaParserCtxtPtr ctxt,
3119
        xmlParserErrors error,
3120
        xmlSchemaTypePtr type,
3121
        xmlSchemaTypePtr baseType,
3122
        xmlSchemaFacetPtr facet)
3123
0
{
3124
0
    xmlChar *des = NULL, *strT = NULL;
3125
3126
0
    xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST type, type->node);
3127
0
    xmlSchemaPErrExt(ctxt, type->node, error, NULL, NULL, NULL,
3128
0
  "%s: The facet '%s' is not allowed on types derived from the "
3129
0
  "type %s.\n",
3130
0
  BAD_CAST des, xmlSchemaFacetTypeToString(facet->type),
3131
0
  xmlSchemaFormatItemForReport(&strT, NULL, WXS_BASIC_CAST baseType, NULL),
3132
0
  NULL, NULL);
3133
0
    FREE_AND_NULL(des);
3134
0
    FREE_AND_NULL(strT);
3135
0
}
3136
3137
/**
3138
 * xmlSchemaPIllegalFacetListUnionErr:
3139
 * @ctxt: the schema parser context
3140
 * @error: the error code
3141
 * @itemDes: the designation of the schema item involved
3142
 * @item: the schema item involved
3143
 * @facet: the illegal facet
3144
 *
3145
 * Reports an illegal facet for <list> and <union>.
3146
 */
3147
static void
3148
xmlSchemaPIllegalFacetListUnionErr(xmlSchemaParserCtxtPtr ctxt,
3149
        xmlParserErrors error,
3150
        xmlSchemaTypePtr type,
3151
        xmlSchemaFacetPtr facet)
3152
0
{
3153
0
    xmlChar *des = NULL;
3154
3155
0
    xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST type,
3156
0
  type->node);
3157
0
    xmlSchemaPErr(ctxt, type->node, error,
3158
0
  "%s: The facet '%s' is not allowed.\n",
3159
0
  BAD_CAST des, xmlSchemaFacetTypeToString(facet->type));
3160
0
    FREE_AND_NULL(des);
3161
0
}
3162
3163
/**
3164
 * xmlSchemaPMutualExclAttrErr:
3165
 * @ctxt: the schema validation context
3166
 * @error: the error code
3167
 * @elemDes: the designation of the parent element node
3168
 * @attr: the bad attribute node
3169
 * @type: the corresponding type of the attribute node
3170
 *
3171
 * Reports an illegal attribute.
3172
 */
3173
static void
3174
xmlSchemaPMutualExclAttrErr(xmlSchemaParserCtxtPtr ctxt,
3175
       xmlParserErrors error,
3176
       xmlSchemaBasicItemPtr ownerItem,
3177
       xmlAttrPtr attr,
3178
       const char *name1,
3179
       const char *name2)
3180
0
{
3181
0
    xmlChar *des = NULL;
3182
3183
0
    xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST ownerItem, attr->parent);
3184
0
    xmlSchemaPErrExt(ctxt, (xmlNodePtr) attr, error, NULL, NULL, NULL,
3185
0
  "%s: The attributes '%s' and '%s' are mutually exclusive.\n",
3186
0
  BAD_CAST des, BAD_CAST name1, BAD_CAST name2, NULL, NULL);
3187
0
    FREE_AND_NULL(des);
3188
0
}
3189
3190
/**
3191
 * xmlSchemaPSimpleTypeErr:
3192
 * @ctxt:  the schema validation context
3193
 * @error: the error code
3194
 * @type: the type specifier
3195
 * @ownerItem: the schema object if existent
3196
 * @node: the validated node
3197
 * @value: the validated value
3198
 *
3199
 * Reports a simple type validation error.
3200
 * TODO: Should this report the value of an element as well?
3201
 */
3202
static void LIBXML_ATTR_FORMAT(8,0)
3203
xmlSchemaPSimpleTypeErr(xmlSchemaParserCtxtPtr ctxt,
3204
      xmlParserErrors error,
3205
      xmlSchemaBasicItemPtr ownerItem ATTRIBUTE_UNUSED,
3206
      xmlNodePtr node,
3207
      xmlSchemaTypePtr type,
3208
      const char *expected,
3209
      const xmlChar *value,
3210
      const char *message,
3211
      const xmlChar *str1,
3212
      const xmlChar *str2)
3213
0
{
3214
0
    xmlChar *msg = NULL;
3215
3216
0
    xmlSchemaFormatNodeForError(&msg, ACTXT_CAST ctxt, node);
3217
0
    if (message == NULL) {
3218
  /*
3219
  * Use default messages.
3220
  */
3221
0
  if (type != NULL) {
3222
0
      if (node->type == XML_ATTRIBUTE_NODE)
3223
0
    msg = xmlStrcat(msg, BAD_CAST "'%s' is not a valid value of ");
3224
0
      else
3225
0
    msg = xmlStrcat(msg, BAD_CAST "The character content is not a "
3226
0
    "valid value of ");
3227
0
      if (! xmlSchemaIsGlobalItem(type))
3228
0
    msg = xmlStrcat(msg, BAD_CAST "the local ");
3229
0
      else
3230
0
    msg = xmlStrcat(msg, BAD_CAST "the ");
3231
3232
0
      if (WXS_IS_ATOMIC(type))
3233
0
    msg = xmlStrcat(msg, BAD_CAST "atomic type");
3234
0
      else if (WXS_IS_LIST(type))
3235
0
    msg = xmlStrcat(msg, BAD_CAST "list type");
3236
0
      else if (WXS_IS_UNION(type))
3237
0
    msg = xmlStrcat(msg, BAD_CAST "union type");
3238
3239
0
      if (xmlSchemaIsGlobalItem(type)) {
3240
0
    xmlChar *str = NULL;
3241
0
    msg = xmlStrcat(msg, BAD_CAST " '");
3242
0
    if (type->builtInType != 0) {
3243
0
        msg = xmlStrcat(msg, BAD_CAST "xs:");
3244
0
        str = xmlStrdup(type->name);
3245
0
    } else {
3246
0
        const xmlChar *qName = xmlSchemaFormatQName(&str, type->targetNamespace, type->name);
3247
0
        if (!str)
3248
0
      str = xmlStrdup(qName);
3249
0
    }
3250
0
    msg = xmlStrcat(msg, xmlEscapeFormatString(&str));
3251
0
    msg = xmlStrcat(msg, BAD_CAST "'.");
3252
0
    FREE_AND_NULL(str);
3253
0
      }
3254
0
  } else {
3255
0
      if (node->type == XML_ATTRIBUTE_NODE)
3256
0
    msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not valid.");
3257
0
      else
3258
0
    msg = xmlStrcat(msg, BAD_CAST "The character content is not "
3259
0
    "valid.");
3260
0
  }
3261
0
  if (expected) {
3262
0
      xmlChar *expectedEscaped = xmlCharStrdup(expected);
3263
0
      msg = xmlStrcat(msg, BAD_CAST " Expected is '");
3264
0
      msg = xmlStrcat(msg, xmlEscapeFormatString(&expectedEscaped));
3265
0
      FREE_AND_NULL(expectedEscaped);
3266
0
      msg = xmlStrcat(msg, BAD_CAST "'.\n");
3267
0
  } else
3268
0
      msg = xmlStrcat(msg, BAD_CAST "\n");
3269
0
  if (node->type == XML_ATTRIBUTE_NODE)
3270
0
      xmlSchemaPErr(ctxt, node, error, (const char *) msg, value, NULL);
3271
0
  else
3272
0
      xmlSchemaPErr(ctxt, node, error, (const char *) msg, NULL, NULL);
3273
0
    } else {
3274
0
  msg = xmlStrcat(msg, BAD_CAST message);
3275
0
  msg = xmlStrcat(msg, BAD_CAST ".\n");
3276
0
  xmlSchemaPErrExt(ctxt, node, error, NULL, NULL, NULL,
3277
0
       (const char*) msg, str1, str2, NULL, NULL, NULL);
3278
0
    }
3279
    /* Cleanup. */
3280
0
    FREE_AND_NULL(msg)
3281
0
}
3282
3283
/**
3284
 * xmlSchemaPContentErr:
3285
 * @ctxt: the schema parser context
3286
 * @error: the error code
3287
 * @ownerItem: the owner item of the holder of the content
3288
 * @ownerElem: the node of the holder of the content
3289
 * @child: the invalid child node
3290
 * @message: the optional error message
3291
 * @content: the optional string describing the correct content
3292
 *
3293
 * Reports an error concerning the content of a schema element.
3294
 */
3295
static void
3296
xmlSchemaPContentErr(xmlSchemaParserCtxtPtr ctxt,
3297
         xmlParserErrors error,
3298
         xmlSchemaBasicItemPtr ownerItem,
3299
         xmlNodePtr ownerElem,
3300
         xmlNodePtr child,
3301
         const char *message,
3302
         const char *content)
3303
0
{
3304
0
    xmlChar *des = NULL;
3305
3306
0
    xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem);
3307
0
    if (message != NULL)
3308
0
  xmlSchemaPErr2(ctxt, ownerElem, child, error,
3309
0
      "%s: %s.\n",
3310
0
      BAD_CAST des, BAD_CAST message);
3311
0
    else {
3312
0
  if (content != NULL) {
3313
0
      xmlSchemaPErr2(ctxt, ownerElem, child, error,
3314
0
    "%s: The content is not valid. Expected is %s.\n",
3315
0
    BAD_CAST des, BAD_CAST content);
3316
0
  } else {
3317
0
      xmlSchemaPErr2(ctxt, ownerElem, child, error,
3318
0
    "%s: The content is not valid.\n",
3319
0
    BAD_CAST des, NULL);
3320
0
  }
3321
0
    }
3322
0
    FREE_AND_NULL(des)
3323
0
}
3324
3325
/************************************************************************
3326
 *                  *
3327
 *      Streamable error functions                      *
3328
 *                  *
3329
 ************************************************************************/
3330
3331
3332
3333
3334
/************************************************************************
3335
 *                  *
3336
 *      Validation helper functions     *
3337
 *                  *
3338
 ************************************************************************/
3339
3340
3341
/************************************************************************
3342
 *                  *
3343
 *      Allocation functions        *
3344
 *                  *
3345
 ************************************************************************/
3346
3347
/**
3348
 * xmlSchemaNewSchemaForParserCtxt:
3349
 * @ctxt:  a schema validation context
3350
 *
3351
 * Allocate a new Schema structure.
3352
 *
3353
 * Returns the newly allocated structure or NULL in case or error
3354
 */
3355
static xmlSchemaPtr
3356
xmlSchemaNewSchema(xmlSchemaParserCtxtPtr ctxt)
3357
0
{
3358
0
    xmlSchemaPtr ret;
3359
3360
0
    ret = (xmlSchemaPtr) xmlMalloc(sizeof(xmlSchema));
3361
0
    if (ret == NULL) {
3362
0
        xmlSchemaPErrMemory(ctxt);
3363
0
        return (NULL);
3364
0
    }
3365
0
    memset(ret, 0, sizeof(xmlSchema));
3366
0
    ret->dict = ctxt->dict;
3367
0
    xmlDictReference(ret->dict);
3368
3369
0
    return (ret);
3370
0
}
3371
3372
/**
3373
 * xmlSchemaNewFacet:
3374
 *
3375
 * Allocate a new Facet structure.
3376
 *
3377
 * Returns the newly allocated structure or NULL in case or error
3378
 */
3379
xmlSchemaFacetPtr
3380
xmlSchemaNewFacet(void)
3381
0
{
3382
0
    xmlSchemaFacetPtr ret;
3383
3384
0
    ret = (xmlSchemaFacetPtr) xmlMalloc(sizeof(xmlSchemaFacet));
3385
0
    if (ret == NULL) {
3386
0
        return (NULL);
3387
0
    }
3388
0
    memset(ret, 0, sizeof(xmlSchemaFacet));
3389
3390
0
    return (ret);
3391
0
}
3392
3393
/**
3394
 * xmlSchemaNewAnnot:
3395
 * @ctxt:  a schema validation context
3396
 * @node:  a node
3397
 *
3398
 * Allocate a new annotation structure.
3399
 *
3400
 * Returns the newly allocated structure or NULL in case or error
3401
 */
3402
static xmlSchemaAnnotPtr
3403
xmlSchemaNewAnnot(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node)
3404
0
{
3405
0
    xmlSchemaAnnotPtr ret;
3406
3407
0
    ret = (xmlSchemaAnnotPtr) xmlMalloc(sizeof(xmlSchemaAnnot));
3408
0
    if (ret == NULL) {
3409
0
        xmlSchemaPErrMemory(ctxt);
3410
0
        return (NULL);
3411
0
    }
3412
0
    memset(ret, 0, sizeof(xmlSchemaAnnot));
3413
0
    ret->content = node;
3414
0
    return (ret);
3415
0
}
3416
3417
static xmlSchemaItemListPtr
3418
xmlSchemaItemListCreate(void)
3419
0
{
3420
0
    xmlSchemaItemListPtr ret;
3421
3422
0
    ret = xmlMalloc(sizeof(xmlSchemaItemList));
3423
0
    if (ret == NULL) {
3424
0
  xmlSchemaPErrMemory(NULL);
3425
0
  return (NULL);
3426
0
    }
3427
0
    memset(ret, 0, sizeof(xmlSchemaItemList));
3428
0
    return (ret);
3429
0
}
3430
3431
static void
3432
xmlSchemaItemListClear(xmlSchemaItemListPtr list)
3433
0
{
3434
0
    if (list->items != NULL) {
3435
0
  xmlFree(list->items);
3436
0
  list->items = NULL;
3437
0
    }
3438
0
    list->nbItems = 0;
3439
0
    list->sizeItems = 0;
3440
0
}
3441
3442
static int
3443
xmlSchemaItemListGrow(xmlSchemaItemListPtr list, int initialSize)
3444
0
{
3445
0
    void **tmp;
3446
0
    int newSize;
3447
3448
0
    if (initialSize <= 0)
3449
0
        initialSize = 1;
3450
0
    newSize = xmlGrowCapacity(list->sizeItems, sizeof(tmp[0]),
3451
0
                              initialSize, XML_MAX_ITEMS);
3452
0
    if (newSize < 0)
3453
0
        return(-1);
3454
0
    tmp = xmlRealloc(list->items, newSize * sizeof(tmp[0]));
3455
0
    if (tmp == NULL)
3456
0
        return(-1);
3457
3458
0
    list->items = tmp;
3459
0
    list->sizeItems = newSize;
3460
0
    return(0);
3461
0
}
3462
3463
static int
3464
xmlSchemaItemListAddSize(xmlSchemaItemListPtr list,
3465
       int initialSize,
3466
       void *item)
3467
0
{
3468
0
    if (list->sizeItems <= list->nbItems) {
3469
0
        if (xmlSchemaItemListGrow(list, initialSize) < 0) {
3470
0
      xmlSchemaPErrMemory(NULL);
3471
0
      return(-1);
3472
0
        }
3473
0
    }
3474
3475
0
    list->items[list->nbItems++] = item;
3476
0
    return(0);
3477
0
}
3478
3479
static int
3480
xmlSchemaItemListAdd(xmlSchemaItemListPtr list, void *item)
3481
0
{
3482
0
    return(xmlSchemaItemListAddSize(list, 20, item));
3483
0
}
3484
3485
static int
3486
xmlSchemaItemListInsert(xmlSchemaItemListPtr list, void *item, int idx)
3487
0
{
3488
0
    if (list->sizeItems <= list->nbItems) {
3489
0
        if (xmlSchemaItemListGrow(list, 20) < 0) {
3490
0
      xmlSchemaPErrMemory(NULL);
3491
0
      return(-1);
3492
0
        }
3493
0
    }
3494
3495
    /*
3496
    * Just append if the index is greater/equal than the item count.
3497
    */
3498
0
    if (idx >= list->nbItems) {
3499
0
  list->items[list->nbItems++] = item;
3500
0
    } else {
3501
0
  int i;
3502
0
  for (i = list->nbItems; i > idx; i--)
3503
0
      list->items[i] = list->items[i-1];
3504
0
  list->items[idx] = item;
3505
0
  list->nbItems++;
3506
0
    }
3507
0
    return(0);
3508
0
}
3509
3510
static int
3511
xmlSchemaItemListRemove(xmlSchemaItemListPtr list, int idx)
3512
0
{
3513
0
    int i;
3514
0
    if ((list->items == NULL) || (idx >= list->nbItems))
3515
0
  return(-1);
3516
3517
0
    if (list->nbItems == 1) {
3518
  /* TODO: Really free the list? */
3519
0
  xmlFree(list->items);
3520
0
  list->items = NULL;
3521
0
  list->nbItems = 0;
3522
0
  list->sizeItems = 0;
3523
0
    } else if (list->nbItems -1 == idx) {
3524
0
  list->nbItems--;
3525
0
    } else {
3526
0
  for (i = idx; i < list->nbItems -1; i++)
3527
0
      list->items[i] = list->items[i+1];
3528
0
  list->nbItems--;
3529
0
    }
3530
0
    return(0);
3531
0
}
3532
3533
/**
3534
 * xmlSchemaItemListFree:
3535
 * @annot:  a schema type structure
3536
 *
3537
 * Deallocate a annotation structure
3538
 */
3539
static void
3540
xmlSchemaItemListFree(xmlSchemaItemListPtr list)
3541
0
{
3542
0
    if (list == NULL)
3543
0
  return;
3544
0
    if (list->items != NULL)
3545
0
  xmlFree(list->items);
3546
0
    xmlFree(list);
3547
0
}
3548
3549
static void
3550
xmlSchemaBucketFree(xmlSchemaBucketPtr bucket)
3551
0
{
3552
0
    if (bucket == NULL)
3553
0
  return;
3554
0
    if (bucket->globals != NULL) {
3555
0
  xmlSchemaComponentListFree(bucket->globals);
3556
0
  xmlSchemaItemListFree(bucket->globals);
3557
0
    }
3558
0
    if (bucket->locals != NULL) {
3559
0
  xmlSchemaComponentListFree(bucket->locals);
3560
0
  xmlSchemaItemListFree(bucket->locals);
3561
0
    }
3562
0
    if (bucket->relations != NULL) {
3563
0
  xmlSchemaSchemaRelationPtr prev, cur = bucket->relations;
3564
0
  do {
3565
0
      prev = cur;
3566
0
      cur = cur->next;
3567
0
      xmlFree(prev);
3568
0
  } while (cur != NULL);
3569
0
    }
3570
0
    if ((! bucket->preserveDoc) && (bucket->doc != NULL)) {
3571
0
  xmlFreeDoc(bucket->doc);
3572
0
    }
3573
0
    if (bucket->type == XML_SCHEMA_SCHEMA_IMPORT) {
3574
0
  if (WXS_IMPBUCKET(bucket)->schema != NULL)
3575
0
      xmlSchemaFree(WXS_IMPBUCKET(bucket)->schema);
3576
0
    }
3577
0
    xmlFree(bucket);
3578
0
}
3579
3580
static void
3581
xmlSchemaBucketFreeEntry(void *bucket, const xmlChar *name ATTRIBUTE_UNUSED)
3582
0
{
3583
0
    xmlSchemaBucketFree((xmlSchemaBucketPtr) bucket);
3584
0
}
3585
3586
static xmlSchemaBucketPtr
3587
xmlSchemaBucketCreate(xmlSchemaParserCtxtPtr pctxt,
3588
       int type, const xmlChar *targetNamespace)
3589
0
{
3590
0
    xmlSchemaBucketPtr ret;
3591
0
    int size;
3592
0
    xmlSchemaPtr mainSchema;
3593
3594
0
    if (WXS_CONSTRUCTOR(pctxt)->mainSchema == NULL) {
3595
0
  PERROR_INT("xmlSchemaBucketCreate",
3596
0
      "no main schema on constructor");
3597
0
  return(NULL);
3598
0
    }
3599
0
    mainSchema = WXS_CONSTRUCTOR(pctxt)->mainSchema;
3600
    /* Create the schema bucket. */
3601
0
    if (WXS_IS_BUCKET_INCREDEF(type))
3602
0
  size = sizeof(xmlSchemaInclude);
3603
0
    else
3604
0
  size = sizeof(xmlSchemaImport);
3605
0
    ret = (xmlSchemaBucketPtr) xmlMalloc(size);
3606
0
    if (ret == NULL) {
3607
0
  xmlSchemaPErrMemory(NULL);
3608
0
  return(NULL);
3609
0
    }
3610
0
    memset(ret, 0, size);
3611
0
    ret->targetNamespace = targetNamespace;
3612
0
    ret->type = type;
3613
0
    ret->globals = xmlSchemaItemListCreate();
3614
0
    if (ret->globals == NULL) {
3615
0
  xmlSchemaBucketFree(ret);
3616
0
  return(NULL);
3617
0
    }
3618
0
    ret->locals = xmlSchemaItemListCreate();
3619
0
    if (ret->locals == NULL) {
3620
0
  xmlSchemaBucketFree(ret);
3621
0
  return(NULL);
3622
0
    }
3623
    /*
3624
    * The following will assure that only the first bucket is marked as
3625
    * XML_SCHEMA_SCHEMA_MAIN and it points to the *main* schema.
3626
    * For each following import buckets an xmlSchema will be created.
3627
    * An xmlSchema will be created for every distinct targetNamespace.
3628
    * We assign the targetNamespace to the schemata here.
3629
    */
3630
0
    if (! WXS_HAS_BUCKETS(pctxt)) {
3631
0
  if (WXS_IS_BUCKET_INCREDEF(type)) {
3632
0
      PERROR_INT("xmlSchemaBucketCreate",
3633
0
    "first bucket but it's an include or redefine");
3634
0
      xmlSchemaBucketFree(ret);
3635
0
      return(NULL);
3636
0
  }
3637
  /* Force the type to be XML_SCHEMA_SCHEMA_MAIN. */
3638
0
  ret->type = XML_SCHEMA_SCHEMA_MAIN;
3639
  /* Point to the *main* schema. */
3640
0
  WXS_CONSTRUCTOR(pctxt)->mainBucket = ret;
3641
0
  WXS_IMPBUCKET(ret)->schema = mainSchema;
3642
  /*
3643
  * Ensure that the main schema gets a targetNamespace.
3644
  */
3645
0
  mainSchema->targetNamespace = targetNamespace;
3646
0
    } else {
3647
0
  if (type == XML_SCHEMA_SCHEMA_MAIN) {
3648
0
      PERROR_INT("xmlSchemaBucketCreate",
3649
0
    "main bucket but it's not the first one");
3650
0
      xmlSchemaBucketFree(ret);
3651
0
      return(NULL);
3652
0
  } else if (type == XML_SCHEMA_SCHEMA_IMPORT) {
3653
      /*
3654
      * Create a schema for imports and assign the
3655
      * targetNamespace.
3656
      */
3657
0
      WXS_IMPBUCKET(ret)->schema = xmlSchemaNewSchema(pctxt);
3658
0
      if (WXS_IMPBUCKET(ret)->schema == NULL) {
3659
0
    xmlSchemaBucketFree(ret);
3660
0
    return(NULL);
3661
0
      }
3662
0
      WXS_IMPBUCKET(ret)->schema->targetNamespace = targetNamespace;
3663
0
  }
3664
0
    }
3665
0
    if (WXS_IS_BUCKET_IMPMAIN(type)) {
3666
0
  int res;
3667
  /*
3668
  * Imports go into the "schemasImports" slot of the main *schema*.
3669
  * Note that we create an import entry for the main schema as well; i.e.,
3670
  * even if there's only one schema, we'll get an import.
3671
  */
3672
0
  if (mainSchema->schemasImports == NULL) {
3673
0
      mainSchema->schemasImports = xmlHashCreateDict(5,
3674
0
    WXS_CONSTRUCTOR(pctxt)->dict);
3675
0
      if (mainSchema->schemasImports == NULL) {
3676
0
    xmlSchemaBucketFree(ret);
3677
0
    return(NULL);
3678
0
      }
3679
0
  }
3680
0
  if (targetNamespace == NULL)
3681
0
      res = xmlHashAddEntry(mainSchema->schemasImports,
3682
0
    XML_SCHEMAS_NO_NAMESPACE, ret);
3683
0
  else
3684
0
      res = xmlHashAddEntry(mainSchema->schemasImports,
3685
0
    targetNamespace, ret);
3686
0
  if (res != 0) {
3687
0
      PERROR_INT("xmlSchemaBucketCreate",
3688
0
    "failed to add the schema bucket to the hash");
3689
0
      xmlSchemaBucketFree(ret);
3690
0
      return(NULL);
3691
0
  }
3692
0
    } else {
3693
  /* Set the @ownerImport of an include bucket. */
3694
0
  if (WXS_IS_BUCKET_IMPMAIN(WXS_CONSTRUCTOR(pctxt)->bucket->type))
3695
0
      WXS_INCBUCKET(ret)->ownerImport =
3696
0
    WXS_IMPBUCKET(WXS_CONSTRUCTOR(pctxt)->bucket);
3697
0
  else
3698
0
      WXS_INCBUCKET(ret)->ownerImport =
3699
0
    WXS_INCBUCKET(WXS_CONSTRUCTOR(pctxt)->bucket)->ownerImport;
3700
3701
  /* Includes got into the "includes" slot of the *main* schema. */
3702
0
  if (mainSchema->includes == NULL) {
3703
0
      mainSchema->includes = xmlSchemaItemListCreate();
3704
0
      if (mainSchema->includes == NULL) {
3705
0
    xmlSchemaBucketFree(ret);
3706
0
    return(NULL);
3707
0
      }
3708
0
  }
3709
0
  if (xmlSchemaItemListAdd(mainSchema->includes, ret) < 0) {
3710
0
      xmlSchemaBucketFree(ret);
3711
0
      return(NULL);
3712
0
        }
3713
0
    }
3714
    /*
3715
    * Add to list of all buckets; this is used for lookup
3716
    * during schema construction time only.
3717
    */
3718
0
    if (xmlSchemaItemListAdd(WXS_CONSTRUCTOR(pctxt)->buckets, ret) == -1)
3719
0
  return(NULL);
3720
0
    return(ret);
3721
0
}
3722
3723
static int
3724
xmlSchemaAddItemSize(xmlSchemaItemListPtr *list, int initialSize, void *item)
3725
0
{
3726
0
    if (*list == NULL) {
3727
0
  *list = xmlSchemaItemListCreate();
3728
0
  if (*list == NULL)
3729
0
      return(-1);
3730
0
    }
3731
0
    return(xmlSchemaItemListAddSize(*list, initialSize, item));
3732
0
}
3733
3734
/**
3735
 * xmlSchemaFreeAnnot:
3736
 * @annot:  a schema type structure
3737
 *
3738
 * Deallocate a annotation structure
3739
 */
3740
static void
3741
xmlSchemaFreeAnnot(xmlSchemaAnnotPtr annot)
3742
0
{
3743
0
    if (annot == NULL)
3744
0
        return;
3745
0
    if (annot->next == NULL) {
3746
0
  xmlFree(annot);
3747
0
    } else {
3748
0
  xmlSchemaAnnotPtr prev;
3749
3750
0
  do {
3751
0
      prev = annot;
3752
0
      annot = annot->next;
3753
0
      xmlFree(prev);
3754
0
  } while (annot != NULL);
3755
0
    }
3756
0
}
3757
3758
/**
3759
 * xmlSchemaFreeNotation:
3760
 * @schema:  a schema notation structure
3761
 *
3762
 * Deallocate a Schema Notation structure.
3763
 */
3764
static void
3765
xmlSchemaFreeNotation(xmlSchemaNotationPtr nota)
3766
0
{
3767
0
    if (nota == NULL)
3768
0
        return;
3769
0
    if (nota->annot != NULL)
3770
0
  xmlSchemaFreeAnnot(nota->annot);
3771
0
    xmlFree(nota);
3772
0
}
3773
3774
/**
3775
 * xmlSchemaFreeAttribute:
3776
 * @attr:  an attribute declaration
3777
 *
3778
 * Deallocates an attribute declaration structure.
3779
 */
3780
static void
3781
xmlSchemaFreeAttribute(xmlSchemaAttributePtr attr)
3782
0
{
3783
0
    if (attr == NULL)
3784
0
        return;
3785
0
    if (attr->annot != NULL)
3786
0
  xmlSchemaFreeAnnot(attr->annot);
3787
0
    if (attr->defVal != NULL)
3788
0
  xmlSchemaFreeValue(attr->defVal);
3789
0
    xmlFree(attr);
3790
0
}
3791
3792
/**
3793
 * xmlSchemaFreeAttributeUse:
3794
 * @use:  an attribute use
3795
 *
3796
 * Deallocates an attribute use structure.
3797
 */
3798
static void
3799
xmlSchemaFreeAttributeUse(xmlSchemaAttributeUsePtr use)
3800
0
{
3801
0
    if (use == NULL)
3802
0
        return;
3803
0
    if (use->annot != NULL)
3804
0
  xmlSchemaFreeAnnot(use->annot);
3805
0
    if (use->defVal != NULL)
3806
0
  xmlSchemaFreeValue(use->defVal);
3807
0
    xmlFree(use);
3808
0
}
3809
3810
/**
3811
 * xmlSchemaFreeAttributeUseProhib:
3812
 * @prohib:  an attribute use prohibition
3813
 *
3814
 * Deallocates an attribute use structure.
3815
 */
3816
static void
3817
xmlSchemaFreeAttributeUseProhib(xmlSchemaAttributeUseProhibPtr prohib)
3818
0
{
3819
0
    if (prohib == NULL)
3820
0
        return;
3821
0
    xmlFree(prohib);
3822
0
}
3823
3824
/**
3825
 * xmlSchemaFreeWildcardNsSet:
3826
 * set:  a schema wildcard namespace
3827
 *
3828
 * Deallocates a list of wildcard constraint structures.
3829
 */
3830
static void
3831
xmlSchemaFreeWildcardNsSet(xmlSchemaWildcardNsPtr set)
3832
0
{
3833
0
    xmlSchemaWildcardNsPtr next;
3834
3835
0
    while (set != NULL) {
3836
0
  next = set->next;
3837
0
  xmlFree(set);
3838
0
  set = next;
3839
0
    }
3840
0
}
3841
3842
/**
3843
 * xmlSchemaFreeWildcard:
3844
 * @wildcard:  a wildcard structure
3845
 *
3846
 * Deallocates a wildcard structure.
3847
 */
3848
void
3849
xmlSchemaFreeWildcard(xmlSchemaWildcardPtr wildcard)
3850
0
{
3851
0
    if (wildcard == NULL)
3852
0
        return;
3853
0
    if (wildcard->annot != NULL)
3854
0
        xmlSchemaFreeAnnot(wildcard->annot);
3855
0
    if (wildcard->nsSet != NULL)
3856
0
  xmlSchemaFreeWildcardNsSet(wildcard->nsSet);
3857
0
    if (wildcard->negNsSet != NULL)
3858
0
  xmlFree(wildcard->negNsSet);
3859
0
    xmlFree(wildcard);
3860
0
}
3861
3862
/**
3863
 * xmlSchemaFreeAttributeGroup:
3864
 * @schema:  a schema attribute group structure
3865
 *
3866
 * Deallocate a Schema Attribute Group structure.
3867
 */
3868
static void
3869
xmlSchemaFreeAttributeGroup(xmlSchemaAttributeGroupPtr attrGr)
3870
0
{
3871
0
    if (attrGr == NULL)
3872
0
        return;
3873
0
    if (attrGr->annot != NULL)
3874
0
        xmlSchemaFreeAnnot(attrGr->annot);
3875
0
    if (attrGr->attrUses != NULL)
3876
0
  xmlSchemaItemListFree(WXS_LIST_CAST attrGr->attrUses);
3877
0
    xmlFree(attrGr);
3878
0
}
3879
3880
/**
3881
 * xmlSchemaFreeQNameRef:
3882
 * @item: a QName reference structure
3883
 *
3884
 * Deallocatea a QName reference structure.
3885
 */
3886
static void
3887
xmlSchemaFreeQNameRef(xmlSchemaQNameRefPtr item)
3888
0
{
3889
0
    xmlFree(item);
3890
0
}
3891
3892
/**
3893
 * xmlSchemaFreeTypeLinkList:
3894
 * @alink: a type link
3895
 *
3896
 * Deallocate a list of types.
3897
 */
3898
static void
3899
xmlSchemaFreeTypeLinkList(xmlSchemaTypeLinkPtr link)
3900
0
{
3901
0
    xmlSchemaTypeLinkPtr next;
3902
3903
0
    while (link != NULL) {
3904
0
  next = link->next;
3905
0
  xmlFree(link);
3906
0
  link = next;
3907
0
    }
3908
0
}
3909
3910
static void
3911
xmlSchemaFreeIDCStateObjList(xmlSchemaIDCStateObjPtr sto)
3912
0
{
3913
0
    xmlSchemaIDCStateObjPtr next;
3914
0
    while (sto != NULL) {
3915
0
  next = sto->next;
3916
0
  if (sto->history != NULL)
3917
0
      xmlFree(sto->history);
3918
0
  if (sto->xpathCtxt != NULL)
3919
0
      xmlFreeStreamCtxt((xmlStreamCtxtPtr) sto->xpathCtxt);
3920
0
  xmlFree(sto);
3921
0
  sto = next;
3922
0
    }
3923
0
}
3924
3925
/**
3926
 * xmlSchemaFreeIDC:
3927
 * @idc: a identity-constraint definition
3928
 *
3929
 * Deallocates an identity-constraint definition.
3930
 */
3931
static void
3932
xmlSchemaFreeIDC(xmlSchemaIDCPtr idcDef)
3933
0
{
3934
0
    xmlSchemaIDCSelectPtr cur, prev;
3935
3936
0
    if (idcDef == NULL)
3937
0
  return;
3938
0
    if (idcDef->annot != NULL)
3939
0
        xmlSchemaFreeAnnot(idcDef->annot);
3940
    /* Selector */
3941
0
    if (idcDef->selector != NULL) {
3942
0
  if (idcDef->selector->xpathComp != NULL)
3943
0
      xmlFreePattern((xmlPatternPtr) idcDef->selector->xpathComp);
3944
0
  xmlFree(idcDef->selector);
3945
0
    }
3946
    /* Fields */
3947
0
    if (idcDef->fields != NULL) {
3948
0
  cur = idcDef->fields;
3949
0
  do {
3950
0
      prev = cur;
3951
0
      cur = cur->next;
3952
0
      if (prev->xpathComp != NULL)
3953
0
    xmlFreePattern((xmlPatternPtr) prev->xpathComp);
3954
0
      xmlFree(prev);
3955
0
  } while (cur != NULL);
3956
0
    }
3957
0
    xmlFree(idcDef);
3958
0
}
3959
3960
/**
3961
 * xmlSchemaFreeElement:
3962
 * @schema:  a schema element structure
3963
 *
3964
 * Deallocate a Schema Element structure.
3965
 */
3966
static void
3967
xmlSchemaFreeElement(xmlSchemaElementPtr elem)
3968
0
{
3969
0
    if (elem == NULL)
3970
0
        return;
3971
0
    if (elem->annot != NULL)
3972
0
        xmlSchemaFreeAnnot(elem->annot);
3973
0
    if (elem->contModel != NULL)
3974
0
        xmlRegFreeRegexp(elem->contModel);
3975
0
    if (elem->defVal != NULL)
3976
0
  xmlSchemaFreeValue(elem->defVal);
3977
0
    xmlFree(elem);
3978
0
}
3979
3980
/**
3981
 * xmlSchemaFreeFacet:
3982
 * @facet:  a schema facet structure
3983
 *
3984
 * Deallocate a Schema Facet structure.
3985
 */
3986
void
3987
xmlSchemaFreeFacet(xmlSchemaFacetPtr facet)
3988
0
{
3989
0
    if (facet == NULL)
3990
0
        return;
3991
0
    if (facet->val != NULL)
3992
0
        xmlSchemaFreeValue(facet->val);
3993
0
    if (facet->regexp != NULL)
3994
0
        xmlRegFreeRegexp(facet->regexp);
3995
0
    if (facet->annot != NULL)
3996
0
        xmlSchemaFreeAnnot(facet->annot);
3997
0
    xmlFree(facet);
3998
0
}
3999
4000
/**
4001
 * xmlSchemaFreeType:
4002
 * @type:  a schema type structure
4003
 *
4004
 * Deallocate a Schema Type structure.
4005
 */
4006
void
4007
xmlSchemaFreeType(xmlSchemaTypePtr type)
4008
0
{
4009
0
    if (type == NULL)
4010
0
        return;
4011
0
    if (type->annot != NULL)
4012
0
        xmlSchemaFreeAnnot(type->annot);
4013
0
    if (type->facets != NULL) {
4014
0
        xmlSchemaFacetPtr facet, next;
4015
4016
0
        facet = type->facets;
4017
0
        while (facet != NULL) {
4018
0
            next = facet->next;
4019
0
            xmlSchemaFreeFacet(facet);
4020
0
            facet = next;
4021
0
        }
4022
0
    }
4023
0
    if (type->attrUses != NULL)
4024
0
  xmlSchemaItemListFree((xmlSchemaItemListPtr) type->attrUses);
4025
0
    if (type->memberTypes != NULL)
4026
0
  xmlSchemaFreeTypeLinkList(type->memberTypes);
4027
0
    if (type->facetSet != NULL) {
4028
0
  xmlSchemaFacetLinkPtr next, link;
4029
4030
0
  link = type->facetSet;
4031
0
  do {
4032
0
      next = link->next;
4033
0
      xmlFree(link);
4034
0
      link = next;
4035
0
  } while (link != NULL);
4036
0
    }
4037
0
    if (type->contModel != NULL)
4038
0
        xmlRegFreeRegexp(type->contModel);
4039
0
    xmlFree(type);
4040
0
}
4041
4042
/**
4043
 * xmlSchemaFreeModelGroupDef:
4044
 * @item:  a schema model group definition
4045
 *
4046
 * Deallocates a schema model group definition.
4047
 */
4048
static void
4049
xmlSchemaFreeModelGroupDef(xmlSchemaModelGroupDefPtr item)
4050
0
{
4051
0
    if (item->annot != NULL)
4052
0
  xmlSchemaFreeAnnot(item->annot);
4053
0
    xmlFree(item);
4054
0
}
4055
4056
/**
4057
 * xmlSchemaFreeModelGroup:
4058
 * @item:  a schema model group
4059
 *
4060
 * Deallocates a schema model group structure.
4061
 */
4062
static void
4063
xmlSchemaFreeModelGroup(xmlSchemaModelGroupPtr item)
4064
0
{
4065
0
    if (item->annot != NULL)
4066
0
  xmlSchemaFreeAnnot(item->annot);
4067
0
    xmlFree(item);
4068
0
}
4069
4070
static void
4071
xmlSchemaComponentListFree(xmlSchemaItemListPtr list)
4072
0
{
4073
0
    if ((list == NULL) || (list->nbItems == 0))
4074
0
  return;
4075
0
    {
4076
0
  xmlSchemaTreeItemPtr item;
4077
0
  xmlSchemaTreeItemPtr *items = (xmlSchemaTreeItemPtr *) list->items;
4078
0
  int i;
4079
4080
0
  for (i = 0; i < list->nbItems; i++) {
4081
0
      item = items[i];
4082
0
      if (item == NULL)
4083
0
    continue;
4084
0
      switch (item->type) {
4085
0
    case XML_SCHEMA_TYPE_SIMPLE:
4086
0
    case XML_SCHEMA_TYPE_COMPLEX:
4087
0
        xmlSchemaFreeType((xmlSchemaTypePtr) item);
4088
0
        break;
4089
0
    case XML_SCHEMA_TYPE_ATTRIBUTE:
4090
0
        xmlSchemaFreeAttribute((xmlSchemaAttributePtr) item);
4091
0
        break;
4092
0
    case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
4093
0
        xmlSchemaFreeAttributeUse((xmlSchemaAttributeUsePtr) item);
4094
0
        break;
4095
0
    case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB:
4096
0
        xmlSchemaFreeAttributeUseProhib(
4097
0
      (xmlSchemaAttributeUseProhibPtr) item);
4098
0
        break;
4099
0
    case XML_SCHEMA_TYPE_ELEMENT:
4100
0
        xmlSchemaFreeElement((xmlSchemaElementPtr) item);
4101
0
        break;
4102
0
    case XML_SCHEMA_TYPE_PARTICLE:
4103
0
        if (item->annot != NULL)
4104
0
      xmlSchemaFreeAnnot(item->annot);
4105
0
        xmlFree(item);
4106
0
        break;
4107
0
    case XML_SCHEMA_TYPE_SEQUENCE:
4108
0
    case XML_SCHEMA_TYPE_CHOICE:
4109
0
    case XML_SCHEMA_TYPE_ALL:
4110
0
        xmlSchemaFreeModelGroup((xmlSchemaModelGroupPtr) item);
4111
0
        break;
4112
0
    case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
4113
0
        xmlSchemaFreeAttributeGroup(
4114
0
      (xmlSchemaAttributeGroupPtr) item);
4115
0
        break;
4116
0
    case XML_SCHEMA_TYPE_GROUP:
4117
0
        xmlSchemaFreeModelGroupDef(
4118
0
      (xmlSchemaModelGroupDefPtr) item);
4119
0
        break;
4120
0
    case XML_SCHEMA_TYPE_ANY:
4121
0
    case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
4122
0
        xmlSchemaFreeWildcard((xmlSchemaWildcardPtr) item);
4123
0
        break;
4124
0
    case XML_SCHEMA_TYPE_IDC_KEY:
4125
0
    case XML_SCHEMA_TYPE_IDC_UNIQUE:
4126
0
    case XML_SCHEMA_TYPE_IDC_KEYREF:
4127
0
        xmlSchemaFreeIDC((xmlSchemaIDCPtr) item);
4128
0
        break;
4129
0
    case XML_SCHEMA_TYPE_NOTATION:
4130
0
        xmlSchemaFreeNotation((xmlSchemaNotationPtr) item);
4131
0
        break;
4132
0
    case XML_SCHEMA_EXTRA_QNAMEREF:
4133
0
        xmlSchemaFreeQNameRef((xmlSchemaQNameRefPtr) item);
4134
0
        break;
4135
0
    default:
4136
        /* TODO: This should never be hit. */
4137
0
        break;
4138
0
      }
4139
0
  }
4140
0
  list->nbItems = 0;
4141
0
    }
4142
0
}
4143
4144
/**
4145
 * xmlSchemaFree:
4146
 * @schema:  a schema structure
4147
 *
4148
 * Deallocate a Schema structure.
4149
 */
4150
void
4151
xmlSchemaFree(xmlSchemaPtr schema)
4152
0
{
4153
0
    if (schema == NULL)
4154
0
        return;
4155
    /*
4156
    * Note that those slots are not responsible for freeing
4157
    * schema components anymore; this will now be done by
4158
    * the schema buckets.
4159
    */
4160
0
    if (schema->notaDecl != NULL)
4161
0
        xmlHashFree(schema->notaDecl, NULL);
4162
0
    if (schema->attrDecl != NULL)
4163
0
        xmlHashFree(schema->attrDecl, NULL);
4164
0
    if (schema->attrgrpDecl != NULL)
4165
0
        xmlHashFree(schema->attrgrpDecl, NULL);
4166
0
    if (schema->elemDecl != NULL)
4167
0
        xmlHashFree(schema->elemDecl, NULL);
4168
0
    if (schema->typeDecl != NULL)
4169
0
        xmlHashFree(schema->typeDecl, NULL);
4170
0
    if (schema->groupDecl != NULL)
4171
0
        xmlHashFree(schema->groupDecl, NULL);
4172
0
    if (schema->idcDef != NULL)
4173
0
        xmlHashFree(schema->idcDef, NULL);
4174
4175
0
    if (schema->schemasImports != NULL)
4176
0
  xmlHashFree(schema->schemasImports, xmlSchemaBucketFreeEntry);
4177
0
    if (schema->includes != NULL) {
4178
0
  xmlSchemaItemListPtr list = (xmlSchemaItemListPtr) schema->includes;
4179
0
  int i;
4180
0
  for (i = 0; i < list->nbItems; i++) {
4181
0
      xmlSchemaBucketFree((xmlSchemaBucketPtr) list->items[i]);
4182
0
  }
4183
0
  xmlSchemaItemListFree(list);
4184
0
    }
4185
0
    if (schema->annot != NULL)
4186
0
        xmlSchemaFreeAnnot(schema->annot);
4187
    /* Never free the doc here, since this will be done by the buckets. */
4188
4189
0
    xmlDictFree(schema->dict);
4190
0
    xmlFree(schema);
4191
0
}
4192
4193
/************************************************************************
4194
 *                  *
4195
 *      Debug functions         *
4196
 *                  *
4197
 ************************************************************************/
4198
4199
#ifdef LIBXML_DEBUG_ENABLED
4200
4201
static void
4202
xmlSchemaTypeDump(xmlSchemaTypePtr type, FILE * output); /* forward */
4203
4204
/**
4205
 * xmlSchemaElementDump:
4206
 * @elem:  an element
4207
 * @output:  the file output
4208
 *
4209
 * Dump the element
4210
 */
4211
static void
4212
xmlSchemaElementDump(void *payload, void *data,
4213
                     const xmlChar * name ATTRIBUTE_UNUSED,
4214
         const xmlChar * namespace ATTRIBUTE_UNUSED,
4215
                     const xmlChar * context ATTRIBUTE_UNUSED)
4216
{
4217
    xmlSchemaElementPtr elem = (xmlSchemaElementPtr) payload;
4218
    FILE *output = (FILE *) data;
4219
    if (elem == NULL)
4220
        return;
4221
4222
4223
    fprintf(output, "Element");
4224
    if (elem->flags & XML_SCHEMAS_ELEM_GLOBAL)
4225
  fprintf(output, " (global)");
4226
    fprintf(output, ": '%s' ", elem->name);
4227
    if (namespace != NULL)
4228
  fprintf(output, "ns '%s'", namespace);
4229
    fprintf(output, "\n");
4230
#if 0
4231
    if ((elem->minOccurs != 1) || (elem->maxOccurs != 1)) {
4232
  fprintf(output, "  min %d ", elem->minOccurs);
4233
        if (elem->maxOccurs >= UNBOUNDED)
4234
            fprintf(output, "max: unbounded\n");
4235
        else if (elem->maxOccurs != 1)
4236
            fprintf(output, "max: %d\n", elem->maxOccurs);
4237
        else
4238
            fprintf(output, "\n");
4239
    }
4240
#endif
4241
    /*
4242
    * Misc other properties.
4243
    */
4244
    if ((elem->flags & XML_SCHEMAS_ELEM_NILLABLE) ||
4245
  (elem->flags & XML_SCHEMAS_ELEM_ABSTRACT) ||
4246
  (elem->flags & XML_SCHEMAS_ELEM_FIXED) ||
4247
  (elem->flags & XML_SCHEMAS_ELEM_DEFAULT)) {
4248
  fprintf(output, "  props: ");
4249
  if (elem->flags & XML_SCHEMAS_ELEM_FIXED)
4250
      fprintf(output, "[fixed] ");
4251
  if (elem->flags & XML_SCHEMAS_ELEM_DEFAULT)
4252
      fprintf(output, "[default] ");
4253
  if (elem->flags & XML_SCHEMAS_ELEM_ABSTRACT)
4254
      fprintf(output, "[abstract] ");
4255
  if (elem->flags & XML_SCHEMAS_ELEM_NILLABLE)
4256
      fprintf(output, "[nillable] ");
4257
  fprintf(output, "\n");
4258
    }
4259
    /*
4260
    * Default/fixed value.
4261
    */
4262
    if (elem->value != NULL)
4263
  fprintf(output, "  value: '%s'\n", elem->value);
4264
    /*
4265
    * Type.
4266
    */
4267
    if (elem->namedType != NULL) {
4268
  fprintf(output, "  type: '%s' ", elem->namedType);
4269
  if (elem->namedTypeNs != NULL)
4270
      fprintf(output, "ns '%s'\n", elem->namedTypeNs);
4271
  else
4272
      fprintf(output, "\n");
4273
    } else if (elem->subtypes != NULL) {
4274
  /*
4275
  * Dump local types.
4276
  */
4277
  xmlSchemaTypeDump(elem->subtypes, output);
4278
    }
4279
    /*
4280
    * Substitution group.
4281
    */
4282
    if (elem->substGroup != NULL) {
4283
  fprintf(output, "  substitutionGroup: '%s' ", elem->substGroup);
4284
  if (elem->substGroupNs != NULL)
4285
      fprintf(output, "ns '%s'\n", elem->substGroupNs);
4286
  else
4287
      fprintf(output, "\n");
4288
    }
4289
}
4290
4291
/**
4292
 * xmlSchemaAnnotDump:
4293
 * @output:  the file output
4294
 * @annot:  a annotation
4295
 *
4296
 * Dump the annotation
4297
 */
4298
static void
4299
xmlSchemaAnnotDump(FILE * output, xmlSchemaAnnotPtr annot)
4300
{
4301
    xmlChar *content;
4302
4303
    if (annot == NULL)
4304
        return;
4305
4306
    content = xmlNodeGetContent(annot->content);
4307
    if (content != NULL) {
4308
        fprintf(output, "  Annot: %s\n", content);
4309
        xmlFree(content);
4310
    } else
4311
        fprintf(output, "  Annot: empty\n");
4312
}
4313
4314
/**
4315
 * xmlSchemaContentModelDump:
4316
 * @particle: the schema particle
4317
 * @output: the file output
4318
 * @depth: the depth used for indentation
4319
 *
4320
 * Dump a SchemaType structure
4321
 */
4322
static void
4323
xmlSchemaContentModelDump(xmlSchemaParticlePtr particle, FILE * output, int depth)
4324
{
4325
    xmlChar *str = NULL;
4326
    xmlSchemaTreeItemPtr term;
4327
    char shift[100];
4328
    int i;
4329
4330
    if (particle == NULL)
4331
  return;
4332
    for (i = 0;((i < depth) && (i < 25));i++)
4333
        shift[2 * i] = shift[2 * i + 1] = ' ';
4334
    shift[2 * i] = shift[2 * i + 1] = 0;
4335
    fprintf(output, "%s", shift);
4336
    if (particle->children == NULL) {
4337
  fprintf(output, "MISSING particle term\n");
4338
  return;
4339
    }
4340
    term = particle->children;
4341
    if (term == NULL) {
4342
  fprintf(output, "(NULL)");
4343
    } else {
4344
  switch (term->type) {
4345
      case XML_SCHEMA_TYPE_ELEMENT:
4346
    fprintf(output, "ELEM '%s'", xmlSchemaFormatQName(&str,
4347
        ((xmlSchemaElementPtr)term)->targetNamespace,
4348
        ((xmlSchemaElementPtr)term)->name));
4349
    FREE_AND_NULL(str);
4350
    break;
4351
      case XML_SCHEMA_TYPE_SEQUENCE:
4352
    fprintf(output, "SEQUENCE");
4353
    break;
4354
      case XML_SCHEMA_TYPE_CHOICE:
4355
    fprintf(output, "CHOICE");
4356
    break;
4357
      case XML_SCHEMA_TYPE_ALL:
4358
    fprintf(output, "ALL");
4359
    break;
4360
      case XML_SCHEMA_TYPE_ANY:
4361
    fprintf(output, "ANY");
4362
    break;
4363
      default:
4364
    fprintf(output, "UNKNOWN\n");
4365
    return;
4366
  }
4367
    }
4368
    if (particle->minOccurs != 1)
4369
  fprintf(output, " min: %d", particle->minOccurs);
4370
    if (particle->maxOccurs >= UNBOUNDED)
4371
  fprintf(output, " max: unbounded");
4372
    else if (particle->maxOccurs != 1)
4373
  fprintf(output, " max: %d", particle->maxOccurs);
4374
    fprintf(output, "\n");
4375
    if (term &&
4376
  ((term->type == XML_SCHEMA_TYPE_SEQUENCE) ||
4377
   (term->type == XML_SCHEMA_TYPE_CHOICE) ||
4378
   (term->type == XML_SCHEMA_TYPE_ALL)) &&
4379
   (term->children != NULL)) {
4380
  xmlSchemaContentModelDump((xmlSchemaParticlePtr) term->children,
4381
      output, depth +1);
4382
    }
4383
    if (particle->next != NULL)
4384
  xmlSchemaContentModelDump((xmlSchemaParticlePtr) particle->next,
4385
    output, depth);
4386
}
4387
4388
/**
4389
 * xmlSchemaAttrUsesDump:
4390
 * @uses:  attribute uses list
4391
 * @output:  the file output
4392
 *
4393
 * Dumps a list of attribute use components.
4394
 */
4395
static void
4396
xmlSchemaAttrUsesDump(xmlSchemaItemListPtr uses, FILE * output)
4397
{
4398
    xmlSchemaAttributeUsePtr use;
4399
    xmlSchemaAttributeUseProhibPtr prohib;
4400
    xmlSchemaQNameRefPtr ref;
4401
    const xmlChar *name, *tns;
4402
    xmlChar *str = NULL;
4403
    int i;
4404
4405
    if ((uses == NULL) || (uses->nbItems == 0))
4406
        return;
4407
4408
    fprintf(output, "  attributes:\n");
4409
    for (i = 0; i < uses->nbItems; i++) {
4410
  use = uses->items[i];
4411
  if (use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) {
4412
      fprintf(output, "  [prohibition] ");
4413
      prohib = (xmlSchemaAttributeUseProhibPtr) use;
4414
      name = prohib->name;
4415
      tns = prohib->targetNamespace;
4416
  } else if (use->type == XML_SCHEMA_EXTRA_QNAMEREF) {
4417
      fprintf(output, "  [reference] ");
4418
      ref = (xmlSchemaQNameRefPtr) use;
4419
      name = ref->name;
4420
      tns = ref->targetNamespace;
4421
  } else {
4422
      fprintf(output, "  [use] ");
4423
      name = WXS_ATTRUSE_DECL_NAME(use);
4424
      tns = WXS_ATTRUSE_DECL_TNS(use);
4425
  }
4426
  fprintf(output, "'%s'\n",
4427
      (const char *) xmlSchemaFormatQName(&str, tns, name));
4428
  FREE_AND_NULL(str);
4429
    }
4430
}
4431
4432
/**
4433
 * xmlSchemaTypeDump:
4434
 * @output:  the file output
4435
 * @type:  a type structure
4436
 *
4437
 * Dump a SchemaType structure
4438
 */
4439
static void
4440
xmlSchemaTypeDump(xmlSchemaTypePtr type, FILE * output)
4441
{
4442
    if (type == NULL) {
4443
        fprintf(output, "Type: NULL\n");
4444
        return;
4445
    }
4446
    fprintf(output, "Type: ");
4447
    if (type->name != NULL)
4448
        fprintf(output, "'%s' ", type->name);
4449
    else
4450
        fprintf(output, "(no name) ");
4451
    if (type->targetNamespace != NULL)
4452
  fprintf(output, "ns '%s' ", type->targetNamespace);
4453
    switch (type->type) {
4454
        case XML_SCHEMA_TYPE_BASIC:
4455
            fprintf(output, "[basic] ");
4456
            break;
4457
        case XML_SCHEMA_TYPE_SIMPLE:
4458
            fprintf(output, "[simple] ");
4459
            break;
4460
        case XML_SCHEMA_TYPE_COMPLEX:
4461
            fprintf(output, "[complex] ");
4462
            break;
4463
        case XML_SCHEMA_TYPE_SEQUENCE:
4464
            fprintf(output, "[sequence] ");
4465
            break;
4466
        case XML_SCHEMA_TYPE_CHOICE:
4467
            fprintf(output, "[choice] ");
4468
            break;
4469
        case XML_SCHEMA_TYPE_ALL:
4470
            fprintf(output, "[all] ");
4471
            break;
4472
        case XML_SCHEMA_TYPE_UR:
4473
            fprintf(output, "[ur] ");
4474
            break;
4475
        case XML_SCHEMA_TYPE_RESTRICTION:
4476
            fprintf(output, "[restriction] ");
4477
            break;
4478
        case XML_SCHEMA_TYPE_EXTENSION:
4479
            fprintf(output, "[extension] ");
4480
            break;
4481
        default:
4482
            fprintf(output, "[unknown type %d] ", type->type);
4483
            break;
4484
    }
4485
    fprintf(output, "content: ");
4486
    switch (type->contentType) {
4487
        case XML_SCHEMA_CONTENT_UNKNOWN:
4488
            fprintf(output, "[unknown] ");
4489
            break;
4490
        case XML_SCHEMA_CONTENT_EMPTY:
4491
            fprintf(output, "[empty] ");
4492
            break;
4493
        case XML_SCHEMA_CONTENT_ELEMENTS:
4494
            fprintf(output, "[element] ");
4495
            break;
4496
        case XML_SCHEMA_CONTENT_MIXED:
4497
            fprintf(output, "[mixed] ");
4498
            break;
4499
        case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS:
4500
  /* not used. */
4501
            break;
4502
        case XML_SCHEMA_CONTENT_BASIC:
4503
            fprintf(output, "[basic] ");
4504
            break;
4505
        case XML_SCHEMA_CONTENT_SIMPLE:
4506
            fprintf(output, "[simple] ");
4507
            break;
4508
        case XML_SCHEMA_CONTENT_ANY:
4509
            fprintf(output, "[any] ");
4510
            break;
4511
    }
4512
    fprintf(output, "\n");
4513
    if (type->base != NULL) {
4514
        fprintf(output, "  base type: '%s'", type->base);
4515
  if (type->baseNs != NULL)
4516
      fprintf(output, " ns '%s'\n", type->baseNs);
4517
  else
4518
      fprintf(output, "\n");
4519
    }
4520
    if (type->attrUses != NULL)
4521
  xmlSchemaAttrUsesDump(type->attrUses, output);
4522
    if (type->annot != NULL)
4523
        xmlSchemaAnnotDump(output, type->annot);
4524
#ifdef DUMP_CONTENT_MODEL
4525
    if ((type->type == XML_SCHEMA_TYPE_COMPLEX) &&
4526
  (type->subtypes != NULL)) {
4527
  xmlSchemaContentModelDump((xmlSchemaParticlePtr) type->subtypes,
4528
      output, 1);
4529
    }
4530
#endif
4531
}
4532
4533
static void
4534
xmlSchemaTypeDumpEntry(void *type, void *output,
4535
                       const xmlChar *name ATTRIBUTE_UNUSED)
4536
{
4537
    xmlSchemaTypeDump((xmlSchemaTypePtr) type, (FILE *) output);
4538
}
4539
4540
/**
4541
 * xmlSchemaDump:
4542
 * @output:  the file output
4543
 * @schema:  a schema structure
4544
 *
4545
 * Dump a Schema structure.
4546
 */
4547
void
4548
xmlSchemaDump(FILE * output, xmlSchemaPtr schema)
4549
{
4550
    if (output == NULL)
4551
        return;
4552
    if (schema == NULL) {
4553
        fprintf(output, "Schemas: NULL\n");
4554
        return;
4555
    }
4556
    fprintf(output, "Schemas: ");
4557
    if (schema->name != NULL)
4558
        fprintf(output, "%s, ", schema->name);
4559
    else
4560
        fprintf(output, "no name, ");
4561
    if (schema->targetNamespace != NULL)
4562
        fprintf(output, "%s", (const char *) schema->targetNamespace);
4563
    else
4564
        fprintf(output, "no target namespace");
4565
    fprintf(output, "\n");
4566
    if (schema->annot != NULL)
4567
        xmlSchemaAnnotDump(output, schema->annot);
4568
    xmlHashScan(schema->typeDecl, xmlSchemaTypeDumpEntry, output);
4569
    xmlHashScanFull(schema->elemDecl, xmlSchemaElementDump, output);
4570
}
4571
4572
#endif /* LIBXML_DEBUG_ENABLED */
4573
4574
/************************************************************************
4575
 *                  *
4576
 *      Utilities         *
4577
 *                  *
4578
 ************************************************************************/
4579
4580
/**
4581
 * xmlSchemaGetPropNode:
4582
 * @node: the element node
4583
 * @name: the name of the attribute
4584
 *
4585
 * Seeks an attribute with a name of @name in
4586
 * no namespace.
4587
 *
4588
 * Returns the attribute or NULL if not present.
4589
 */
4590
static xmlAttrPtr
4591
xmlSchemaGetPropNode(xmlNodePtr node, const char *name)
4592
0
{
4593
0
    xmlAttrPtr prop;
4594
4595
0
    if ((node == NULL) || (name == NULL))
4596
0
  return(NULL);
4597
0
    prop = node->properties;
4598
0
    while (prop != NULL) {
4599
0
        if ((prop->ns == NULL) && xmlStrEqual(prop->name, BAD_CAST name))
4600
0
      return(prop);
4601
0
  prop = prop->next;
4602
0
    }
4603
0
    return (NULL);
4604
0
}
4605
4606
/**
4607
 * xmlSchemaGetPropNodeNs:
4608
 * @node: the element node
4609
 * @uri: the uri
4610
 * @name: the name of the attribute
4611
 *
4612
 * Seeks an attribute with a local name of @name and
4613
 * a namespace URI of @uri.
4614
 *
4615
 * Returns the attribute or NULL if not present.
4616
 */
4617
static xmlAttrPtr
4618
xmlSchemaGetPropNodeNs(xmlNodePtr node, const char *uri, const char *name)
4619
0
{
4620
0
    xmlAttrPtr prop;
4621
4622
0
    if ((node == NULL) || (name == NULL))
4623
0
  return(NULL);
4624
0
    prop = node->properties;
4625
0
    while (prop != NULL) {
4626
0
  if ((prop->ns != NULL) &&
4627
0
      xmlStrEqual(prop->name, BAD_CAST name) &&
4628
0
      xmlStrEqual(prop->ns->href, BAD_CAST uri))
4629
0
      return(prop);
4630
0
  prop = prop->next;
4631
0
    }
4632
0
    return (NULL);
4633
0
}
4634
4635
static const xmlChar *
4636
xmlSchemaGetNodeContent(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node)
4637
0
{
4638
0
    xmlChar *val;
4639
0
    const xmlChar *ret;
4640
4641
0
    val = xmlNodeGetContent(node);
4642
0
    if (val == NULL)
4643
0
  val = xmlStrdup((xmlChar *)"");
4644
0
    ret = xmlDictLookup(ctxt->dict, val, -1);
4645
0
    xmlFree(val);
4646
0
    if (ret == NULL)
4647
0
        xmlSchemaPErrMemory(ctxt);
4648
0
    return(ret);
4649
0
}
4650
4651
static const xmlChar *
4652
xmlSchemaGetNodeContentNoDict(xmlNodePtr node)
4653
0
{
4654
0
    return((const xmlChar*) xmlNodeGetContent(node));
4655
0
}
4656
4657
/**
4658
 * xmlSchemaGetProp:
4659
 * @ctxt: the parser context
4660
 * @node: the node
4661
 * @name: the property name
4662
 *
4663
 * Read a attribute value and internalize the string
4664
 *
4665
 * Returns the string or NULL if not present.
4666
 */
4667
static const xmlChar *
4668
xmlSchemaGetProp(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
4669
                 const char *name)
4670
0
{
4671
0
    xmlChar *val;
4672
0
    const xmlChar *ret;
4673
4674
0
    val = xmlGetNoNsProp(node, BAD_CAST name);
4675
0
    if (val == NULL)
4676
0
        return(NULL);
4677
0
    ret = xmlDictLookup(ctxt->dict, val, -1);
4678
0
    xmlFree(val);
4679
0
    return(ret);
4680
0
}
4681
4682
/************************************************************************
4683
 *                  *
4684
 *      Parsing functions       *
4685
 *                  *
4686
 ************************************************************************/
4687
4688
#define WXS_FIND_GLOBAL_ITEM(slot)      \
4689
0
    if (xmlStrEqual(nsName, schema->targetNamespace)) { \
4690
0
  ret = xmlHashLookup(schema->slot, name); \
4691
0
  if (ret != NULL) goto exit; \
4692
0
    } \
4693
0
    if (xmlHashSize(schema->schemasImports) > 1) { \
4694
0
  xmlSchemaImportPtr import; \
4695
0
  if (nsName == NULL) \
4696
0
      import = xmlHashLookup(schema->schemasImports, \
4697
0
    XML_SCHEMAS_NO_NAMESPACE); \
4698
0
  else \
4699
0
      import = xmlHashLookup(schema->schemasImports, nsName); \
4700
0
  if (import == NULL) \
4701
0
      goto exit; \
4702
0
  ret = xmlHashLookup(import->schema->slot, name); \
4703
0
    }
4704
4705
/**
4706
 * xmlSchemaGetElem:
4707
 * @schema:  the schema context
4708
 * @name:  the element name
4709
 * @ns:  the element namespace
4710
 *
4711
 * Lookup a global element declaration in the schema.
4712
 *
4713
 * Returns the element declaration or NULL if not found.
4714
 */
4715
static xmlSchemaElementPtr
4716
xmlSchemaGetElem(xmlSchemaPtr schema, const xmlChar * name,
4717
                 const xmlChar * nsName)
4718
0
{
4719
0
    xmlSchemaElementPtr ret = NULL;
4720
4721
0
    if ((name == NULL) || (schema == NULL))
4722
0
        return(NULL);
4723
0
    if (schema != NULL) {
4724
0
  WXS_FIND_GLOBAL_ITEM(elemDecl)
4725
0
    }
4726
0
exit:
4727
0
    return (ret);
4728
0
}
4729
4730
/**
4731
 * xmlSchemaGetType:
4732
 * @schema:  the main schema
4733
 * @name:  the type's name
4734
 * nsName:  the type's namespace
4735
 *
4736
 * Lookup a type in the schemas or the predefined types
4737
 *
4738
 * Returns the group definition or NULL if not found.
4739
 */
4740
static xmlSchemaTypePtr
4741
xmlSchemaGetType(xmlSchemaPtr schema, const xmlChar * name,
4742
                 const xmlChar * nsName)
4743
0
{
4744
0
    xmlSchemaTypePtr ret = NULL;
4745
4746
0
    if (name == NULL)
4747
0
        return (NULL);
4748
    /* First try the built-in types. */
4749
0
    if ((nsName != NULL) && xmlStrEqual(nsName, xmlSchemaNs)) {
4750
0
  ret = xmlSchemaGetPredefinedType(name, nsName);
4751
0
  if (ret != NULL)
4752
0
      goto exit;
4753
  /*
4754
  * Note that we try the parsed schemas as well here
4755
  * since one might have parsed the S4S, which contain more
4756
  * than the built-in types.
4757
  * TODO: Can we optimize this?
4758
  */
4759
0
    }
4760
0
    if (schema != NULL) {
4761
0
  WXS_FIND_GLOBAL_ITEM(typeDecl)
4762
0
    }
4763
0
exit:
4764
4765
0
    return (ret);
4766
0
}
4767
4768
/**
4769
 * xmlSchemaGetAttributeDecl:
4770
 * @schema:  the context of the schema
4771
 * @name:  the name of the attribute
4772
 * @ns:  the target namespace of the attribute
4773
 *
4774
 * Lookup a an attribute in the schema or imported schemas
4775
 *
4776
 * Returns the attribute declaration or NULL if not found.
4777
 */
4778
static xmlSchemaAttributePtr
4779
xmlSchemaGetAttributeDecl(xmlSchemaPtr schema, const xmlChar * name,
4780
                 const xmlChar * nsName)
4781
0
{
4782
0
    xmlSchemaAttributePtr ret = NULL;
4783
4784
0
    if ((name == NULL) || (schema == NULL))
4785
0
        return (NULL);
4786
0
    if (schema != NULL) {
4787
0
  WXS_FIND_GLOBAL_ITEM(attrDecl)
4788
0
    }
4789
0
exit:
4790
0
    return (ret);
4791
0
}
4792
4793
/**
4794
 * xmlSchemaGetAttributeGroup:
4795
 * @schema:  the context of the schema
4796
 * @name:  the name of the attribute group
4797
 * @ns:  the target namespace of the attribute group
4798
 *
4799
 * Lookup a an attribute group in the schema or imported schemas
4800
 *
4801
 * Returns the attribute group definition or NULL if not found.
4802
 */
4803
static xmlSchemaAttributeGroupPtr
4804
xmlSchemaGetAttributeGroup(xmlSchemaPtr schema, const xmlChar * name,
4805
                 const xmlChar * nsName)
4806
0
{
4807
0
    xmlSchemaAttributeGroupPtr ret = NULL;
4808
4809
0
    if ((name == NULL) || (schema == NULL))
4810
0
        return (NULL);
4811
0
    if (schema != NULL) {
4812
0
  WXS_FIND_GLOBAL_ITEM(attrgrpDecl)
4813
0
    }
4814
0
exit:
4815
    /* TODO:
4816
    if ((ret != NULL) && (ret->redef != NULL)) {
4817
  * Return the last redefinition. *
4818
  ret = ret->redef;
4819
    }
4820
    */
4821
0
    return (ret);
4822
0
}
4823
4824
/**
4825
 * xmlSchemaGetGroup:
4826
 * @schema:  the context of the schema
4827
 * @name:  the name of the group
4828
 * @ns:  the target namespace of the group
4829
 *
4830
 * Lookup a group in the schema or imported schemas
4831
 *
4832
 * Returns the group definition or NULL if not found.
4833
 */
4834
static xmlSchemaModelGroupDefPtr
4835
xmlSchemaGetGroup(xmlSchemaPtr schema, const xmlChar * name,
4836
                 const xmlChar * nsName)
4837
0
{
4838
0
    xmlSchemaModelGroupDefPtr ret = NULL;
4839
4840
0
    if ((name == NULL) || (schema == NULL))
4841
0
        return (NULL);
4842
0
    if (schema != NULL) {
4843
0
  WXS_FIND_GLOBAL_ITEM(groupDecl)
4844
0
    }
4845
0
exit:
4846
4847
0
    return (ret);
4848
0
}
4849
4850
static xmlSchemaNotationPtr
4851
xmlSchemaGetNotation(xmlSchemaPtr schema,
4852
         const xmlChar *name,
4853
         const xmlChar *nsName)
4854
0
{
4855
0
    xmlSchemaNotationPtr ret = NULL;
4856
4857
0
    if ((name == NULL) || (schema == NULL))
4858
0
        return (NULL);
4859
0
    if (schema != NULL) {
4860
0
  WXS_FIND_GLOBAL_ITEM(notaDecl)
4861
0
    }
4862
0
exit:
4863
0
    return (ret);
4864
0
}
4865
4866
static xmlSchemaIDCPtr
4867
xmlSchemaGetIDC(xmlSchemaPtr schema,
4868
    const xmlChar *name,
4869
    const xmlChar *nsName)
4870
0
{
4871
0
    xmlSchemaIDCPtr ret = NULL;
4872
4873
0
    if ((name == NULL) || (schema == NULL))
4874
0
        return (NULL);
4875
0
    if (schema != NULL) {
4876
0
  WXS_FIND_GLOBAL_ITEM(idcDef)
4877
0
    }
4878
0
exit:
4879
0
    return (ret);
4880
0
}
4881
4882
/**
4883
 * xmlSchemaGetNamedComponent:
4884
 * @schema:  the schema
4885
 * @name:  the name of the group
4886
 * @ns:  the target namespace of the group
4887
 *
4888
 * Lookup a group in the schema or imported schemas
4889
 *
4890
 * Returns the group definition or NULL if not found.
4891
 */
4892
static xmlSchemaBasicItemPtr
4893
xmlSchemaGetNamedComponent(xmlSchemaPtr schema,
4894
         xmlSchemaTypeType itemType,
4895
         const xmlChar *name,
4896
         const xmlChar *targetNs)
4897
0
{
4898
0
    switch (itemType) {
4899
0
  case XML_SCHEMA_TYPE_GROUP:
4900
0
      return ((xmlSchemaBasicItemPtr) xmlSchemaGetGroup(schema,
4901
0
    name, targetNs));
4902
0
  case XML_SCHEMA_TYPE_ELEMENT:
4903
0
      return ((xmlSchemaBasicItemPtr) xmlSchemaGetElem(schema,
4904
0
    name, targetNs));
4905
0
  default:
4906
      /* TODO */
4907
0
      return (NULL);
4908
0
    }
4909
0
}
4910
4911
/************************************************************************
4912
 *                  *
4913
 *      Parsing functions       *
4914
 *                  *
4915
 ************************************************************************/
4916
4917
#define IS_BLANK_NODE(n)            \
4918
0
    (((n)->type == XML_TEXT_NODE) && (xmlSchemaIsBlank((n)->content, -1)))
4919
4920
/**
4921
 * xmlSchemaIsBlank:
4922
 * @str:  a string
4923
 * @len: the length of the string or -1
4924
 *
4925
 * Check if a string is ignorable
4926
 *
4927
 * Returns 1 if the string is NULL or made of blanks chars, 0 otherwise
4928
 */
4929
static int
4930
xmlSchemaIsBlank(xmlChar * str, int len)
4931
0
{
4932
0
    if (str == NULL)
4933
0
        return (1);
4934
0
    if (len < 0) {
4935
0
  while (*str != 0) {
4936
0
      if (!(IS_BLANK_CH(*str)))
4937
0
    return (0);
4938
0
      str++;
4939
0
  }
4940
0
    } else while ((*str != 0) && (len != 0)) {
4941
0
  if (!(IS_BLANK_CH(*str)))
4942
0
      return (0);
4943
0
  str++;
4944
0
  len--;
4945
0
    }
4946
4947
0
    return (1);
4948
0
}
4949
4950
0
#define WXS_COMP_NAME(c, t) ((t) (c))->name
4951
0
#define WXS_COMP_TNS(c, t) ((t) (c))->targetNamespace
4952
/*
4953
* xmlSchemaFindRedefCompInGraph:
4954
* ATTENTION TODO: This uses pointer comp. for strings.
4955
*/
4956
static xmlSchemaBasicItemPtr
4957
xmlSchemaFindRedefCompInGraph(xmlSchemaBucketPtr bucket,
4958
            xmlSchemaTypeType type,
4959
            const xmlChar *name,
4960
            const xmlChar *nsName)
4961
0
{
4962
0
    xmlSchemaBasicItemPtr ret;
4963
0
    int i;
4964
4965
0
    if ((bucket == NULL) || (name == NULL))
4966
0
  return(NULL);
4967
0
    if ((bucket->globals == NULL) ||
4968
0
  (bucket->globals->nbItems == 0))
4969
0
  goto subschemas;
4970
    /*
4971
    * Search in global components.
4972
    */
4973
0
    for (i = 0; i < bucket->globals->nbItems; i++) {
4974
0
  ret = bucket->globals->items[i];
4975
0
  if (ret->type == type) {
4976
0
      switch (type) {
4977
0
    case XML_SCHEMA_TYPE_COMPLEX:
4978
0
    case XML_SCHEMA_TYPE_SIMPLE:
4979
0
        if ((WXS_COMP_NAME(ret, xmlSchemaTypePtr) == name) &&
4980
0
      (WXS_COMP_TNS(ret, xmlSchemaTypePtr) ==
4981
0
      nsName))
4982
0
        {
4983
0
      return(ret);
4984
0
        }
4985
0
        break;
4986
0
    case XML_SCHEMA_TYPE_GROUP:
4987
0
        if ((WXS_COMP_NAME(ret,
4988
0
          xmlSchemaModelGroupDefPtr) == name) &&
4989
0
      (WXS_COMP_TNS(ret,
4990
0
          xmlSchemaModelGroupDefPtr) == nsName))
4991
0
        {
4992
0
      return(ret);
4993
0
        }
4994
0
        break;
4995
0
    case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
4996
0
        if ((WXS_COMP_NAME(ret,
4997
0
          xmlSchemaAttributeGroupPtr) == name) &&
4998
0
      (WXS_COMP_TNS(ret,
4999
0
          xmlSchemaAttributeGroupPtr) == nsName))
5000
0
        {
5001
0
      return(ret);
5002
0
        }
5003
0
        break;
5004
0
    default:
5005
        /* Should not be hit. */
5006
0
        return(NULL);
5007
0
      }
5008
0
  }
5009
0
    }
5010
0
subschemas:
5011
    /*
5012
    * Process imported/included schemas.
5013
    */
5014
0
    if (bucket->relations != NULL) {
5015
0
  xmlSchemaSchemaRelationPtr rel = bucket->relations;
5016
5017
  /*
5018
  * TODO: Marking the bucket will not avoid multiple searches
5019
  * in the same schema, but avoids at least circularity.
5020
  */
5021
0
  bucket->flags |= XML_SCHEMA_BUCKET_MARKED;
5022
0
  do {
5023
0
      if ((rel->bucket != NULL) &&
5024
0
    ((rel->bucket->flags & XML_SCHEMA_BUCKET_MARKED) == 0)) {
5025
0
    ret = xmlSchemaFindRedefCompInGraph(rel->bucket,
5026
0
        type, name, nsName);
5027
0
    if (ret != NULL)
5028
0
        return(ret);
5029
0
      }
5030
0
      rel = rel->next;
5031
0
  } while (rel != NULL);
5032
0
   bucket->flags ^= XML_SCHEMA_BUCKET_MARKED;
5033
0
    }
5034
0
    return(NULL);
5035
0
}
5036
5037
/**
5038
 * xmlSchemaAddNotation:
5039
 * @ctxt:  a schema parser context
5040
 * @schema:  the schema being built
5041
 * @name:  the item name
5042
 *
5043
 * Add an XML schema annotation declaration
5044
 * *WARNING* this interface is highly subject to change
5045
 *
5046
 * Returns the new structure or NULL in case of error
5047
 */
5048
static xmlSchemaNotationPtr
5049
xmlSchemaAddNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
5050
                     const xmlChar *name, const xmlChar *nsName,
5051
         xmlNodePtr node ATTRIBUTE_UNUSED)
5052
0
{
5053
0
    xmlSchemaNotationPtr ret = NULL;
5054
5055
0
    if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
5056
0
        return (NULL);
5057
5058
0
    ret = (xmlSchemaNotationPtr) xmlMalloc(sizeof(xmlSchemaNotation));
5059
0
    if (ret == NULL) {
5060
0
        xmlSchemaPErrMemory(ctxt);
5061
0
        return (NULL);
5062
0
    }
5063
0
    memset(ret, 0, sizeof(xmlSchemaNotation));
5064
0
    ret->type = XML_SCHEMA_TYPE_NOTATION;
5065
0
    ret->name = name;
5066
0
    ret->targetNamespace = nsName;
5067
    /* TODO: do we need the node to be set?
5068
    * ret->node = node;*/
5069
0
    WXS_ADD_GLOBAL(ctxt, ret);
5070
0
    return (ret);
5071
0
}
5072
5073
/**
5074
 * xmlSchemaAddAttribute:
5075
 * @ctxt:  a schema parser context
5076
 * @schema:  the schema being built
5077
 * @name:  the item name
5078
 * @namespace:  the namespace
5079
 *
5080
 * Add an XML schema Attribute declaration
5081
 * *WARNING* this interface is highly subject to change
5082
 *
5083
 * Returns the new structure or NULL in case of error
5084
 */
5085
static xmlSchemaAttributePtr
5086
xmlSchemaAddAttribute(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
5087
                      const xmlChar * name, const xmlChar * nsName,
5088
          xmlNodePtr node, int topLevel)
5089
0
{
5090
0
    xmlSchemaAttributePtr ret = NULL;
5091
5092
0
    if ((ctxt == NULL) || (schema == NULL))
5093
0
        return (NULL);
5094
5095
0
    ret = (xmlSchemaAttributePtr) xmlMalloc(sizeof(xmlSchemaAttribute));
5096
0
    if (ret == NULL) {
5097
0
        xmlSchemaPErrMemory(ctxt);
5098
0
        return (NULL);
5099
0
    }
5100
0
    memset(ret, 0, sizeof(xmlSchemaAttribute));
5101
0
    ret->type = XML_SCHEMA_TYPE_ATTRIBUTE;
5102
0
    ret->node = node;
5103
0
    ret->name = name;
5104
0
    ret->targetNamespace = nsName;
5105
5106
0
    if (topLevel)
5107
0
  WXS_ADD_GLOBAL(ctxt, ret);
5108
0
    else
5109
0
  WXS_ADD_LOCAL(ctxt, ret);
5110
0
    WXS_ADD_PENDING(ctxt, ret);
5111
0
    return (ret);
5112
0
}
5113
5114
/**
5115
 * xmlSchemaAddAttributeUse:
5116
 * @ctxt:  a schema parser context
5117
 * @schema:  the schema being built
5118
 * @name:  the item name
5119
 * @namespace:  the namespace
5120
 *
5121
 * Add an XML schema Attribute declaration
5122
 * *WARNING* this interface is highly subject to change
5123
 *
5124
 * Returns the new structure or NULL in case of error
5125
 */
5126
static xmlSchemaAttributeUsePtr
5127
xmlSchemaAddAttributeUse(xmlSchemaParserCtxtPtr pctxt,
5128
       xmlNodePtr node)
5129
0
{
5130
0
    xmlSchemaAttributeUsePtr ret = NULL;
5131
5132
0
    if (pctxt == NULL)
5133
0
        return (NULL);
5134
5135
0
    ret = (xmlSchemaAttributeUsePtr) xmlMalloc(sizeof(xmlSchemaAttributeUse));
5136
0
    if (ret == NULL) {
5137
0
        xmlSchemaPErrMemory(pctxt);
5138
0
        return (NULL);
5139
0
    }
5140
0
    memset(ret, 0, sizeof(xmlSchemaAttributeUse));
5141
0
    ret->type = XML_SCHEMA_TYPE_ATTRIBUTE_USE;
5142
0
    ret->node = node;
5143
5144
0
    WXS_ADD_LOCAL(pctxt, ret);
5145
0
    return (ret);
5146
0
}
5147
5148
/*
5149
* xmlSchemaAddRedef:
5150
*
5151
* Adds a redefinition information. This is used at a later stage to:
5152
* resolve references to the redefined components and to check constraints.
5153
*/
5154
static xmlSchemaRedefPtr
5155
xmlSchemaAddRedef(xmlSchemaParserCtxtPtr pctxt,
5156
      xmlSchemaBucketPtr targetBucket,
5157
      void *item,
5158
      const xmlChar *refName,
5159
      const xmlChar *refTargetNs)
5160
0
{
5161
0
    xmlSchemaRedefPtr ret;
5162
5163
0
    ret = (xmlSchemaRedefPtr)
5164
0
  xmlMalloc(sizeof(xmlSchemaRedef));
5165
0
    if (ret == NULL) {
5166
0
  xmlSchemaPErrMemory(pctxt);
5167
0
  return (NULL);
5168
0
    }
5169
0
    memset(ret, 0, sizeof(xmlSchemaRedef));
5170
0
    ret->item = item;
5171
0
    ret->targetBucket = targetBucket;
5172
0
    ret->refName = refName;
5173
0
    ret->refTargetNs = refTargetNs;
5174
0
    if (WXS_CONSTRUCTOR(pctxt)->redefs == NULL)
5175
0
  WXS_CONSTRUCTOR(pctxt)->redefs = ret;
5176
0
    else
5177
0
  WXS_CONSTRUCTOR(pctxt)->lastRedef->next = ret;
5178
0
    WXS_CONSTRUCTOR(pctxt)->lastRedef = ret;
5179
5180
0
    return (ret);
5181
0
}
5182
5183
/**
5184
 * xmlSchemaAddAttributeGroupDefinition:
5185
 * @ctxt:  a schema parser context
5186
 * @schema:  the schema being built
5187
 * @name:  the item name
5188
 * @nsName:  the target namespace
5189
 * @node: the corresponding node
5190
 *
5191
 * Add an XML schema Attribute Group definition.
5192
 *
5193
 * Returns the new structure or NULL in case of error
5194
 */
5195
static xmlSchemaAttributeGroupPtr
5196
xmlSchemaAddAttributeGroupDefinition(xmlSchemaParserCtxtPtr pctxt,
5197
                           xmlSchemaPtr schema ATTRIBUTE_UNUSED,
5198
         const xmlChar *name,
5199
         const xmlChar *nsName,
5200
         xmlNodePtr node)
5201
0
{
5202
0
    xmlSchemaAttributeGroupPtr ret = NULL;
5203
5204
0
    if ((pctxt == NULL) || (name == NULL))
5205
0
        return (NULL);
5206
5207
0
    ret = (xmlSchemaAttributeGroupPtr)
5208
0
        xmlMalloc(sizeof(xmlSchemaAttributeGroup));
5209
0
    if (ret == NULL) {
5210
0
  xmlSchemaPErrMemory(pctxt);
5211
0
  return (NULL);
5212
0
    }
5213
0
    memset(ret, 0, sizeof(xmlSchemaAttributeGroup));
5214
0
    ret->type = XML_SCHEMA_TYPE_ATTRIBUTEGROUP;
5215
0
    ret->name = name;
5216
0
    ret->targetNamespace = nsName;
5217
0
    ret->node = node;
5218
5219
    /* TODO: Remove the flag. */
5220
0
    ret->flags |= XML_SCHEMAS_ATTRGROUP_GLOBAL;
5221
0
    if (pctxt->isRedefine) {
5222
0
  pctxt->redef = xmlSchemaAddRedef(pctxt, pctxt->redefined,
5223
0
      ret, name, nsName);
5224
0
  if (pctxt->redef == NULL) {
5225
0
      xmlFree(ret);
5226
0
      return(NULL);
5227
0
  }
5228
0
  pctxt->redefCounter = 0;
5229
0
    }
5230
0
    WXS_ADD_GLOBAL(pctxt, ret);
5231
0
    WXS_ADD_PENDING(pctxt, ret);
5232
0
    return (ret);
5233
0
}
5234
5235
/**
5236
 * xmlSchemaAddElement:
5237
 * @ctxt:  a schema parser context
5238
 * @schema:  the schema being built
5239
 * @name:  the type name
5240
 * @namespace:  the type namespace
5241
 *
5242
 * Add an XML schema Element declaration
5243
 * *WARNING* this interface is highly subject to change
5244
 *
5245
 * Returns the new structure or NULL in case of error
5246
 */
5247
static xmlSchemaElementPtr
5248
xmlSchemaAddElement(xmlSchemaParserCtxtPtr ctxt,
5249
                    const xmlChar * name, const xmlChar * nsName,
5250
        xmlNodePtr node, int topLevel)
5251
0
{
5252
0
    xmlSchemaElementPtr ret = NULL;
5253
5254
0
    if ((ctxt == NULL) || (name == NULL))
5255
0
        return (NULL);
5256
5257
0
    ret = (xmlSchemaElementPtr) xmlMalloc(sizeof(xmlSchemaElement));
5258
0
    if (ret == NULL) {
5259
0
        xmlSchemaPErrMemory(ctxt);
5260
0
        return (NULL);
5261
0
    }
5262
0
    memset(ret, 0, sizeof(xmlSchemaElement));
5263
0
    ret->type = XML_SCHEMA_TYPE_ELEMENT;
5264
0
    ret->name = name;
5265
0
    ret->targetNamespace = nsName;
5266
0
    ret->node = node;
5267
5268
0
    if (topLevel)
5269
0
  WXS_ADD_GLOBAL(ctxt, ret);
5270
0
    else
5271
0
  WXS_ADD_LOCAL(ctxt, ret);
5272
0
    WXS_ADD_PENDING(ctxt, ret);
5273
0
    return (ret);
5274
0
}
5275
5276
/**
5277
 * xmlSchemaAddType:
5278
 * @ctxt:  a schema parser context
5279
 * @schema:  the schema being built
5280
 * @name:  the item name
5281
 * @namespace:  the namespace
5282
 *
5283
 * Add an XML schema item
5284
 * *WARNING* this interface is highly subject to change
5285
 *
5286
 * Returns the new structure or NULL in case of error
5287
 */
5288
static xmlSchemaTypePtr
5289
xmlSchemaAddType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
5290
     xmlSchemaTypeType type,
5291
                 const xmlChar * name, const xmlChar * nsName,
5292
     xmlNodePtr node, int topLevel)
5293
0
{
5294
0
    xmlSchemaTypePtr ret = NULL;
5295
5296
0
    if ((ctxt == NULL) || (schema == NULL))
5297
0
        return (NULL);
5298
5299
0
    ret = (xmlSchemaTypePtr) xmlMalloc(sizeof(xmlSchemaType));
5300
0
    if (ret == NULL) {
5301
0
        xmlSchemaPErrMemory(ctxt);
5302
0
        return (NULL);
5303
0
    }
5304
0
    memset(ret, 0, sizeof(xmlSchemaType));
5305
0
    ret->type = type;
5306
0
    ret->name = name;
5307
0
    ret->targetNamespace = nsName;
5308
0
    ret->node = node;
5309
0
    if (topLevel) {
5310
0
  if (ctxt->isRedefine) {
5311
0
      ctxt->redef = xmlSchemaAddRedef(ctxt, ctxt->redefined,
5312
0
    ret, name, nsName);
5313
0
      if (ctxt->redef == NULL) {
5314
0
    xmlFree(ret);
5315
0
    return(NULL);
5316
0
      }
5317
0
      ctxt->redefCounter = 0;
5318
0
  }
5319
0
  WXS_ADD_GLOBAL(ctxt, ret);
5320
0
    } else
5321
0
  WXS_ADD_LOCAL(ctxt, ret);
5322
0
    WXS_ADD_PENDING(ctxt, ret);
5323
0
    return (ret);
5324
0
}
5325
5326
static xmlSchemaQNameRefPtr
5327
xmlSchemaNewQNameRef(xmlSchemaParserCtxtPtr pctxt,
5328
         xmlSchemaTypeType refType,
5329
         const xmlChar *refName,
5330
         const xmlChar *refNs)
5331
0
{
5332
0
    xmlSchemaQNameRefPtr ret;
5333
5334
0
    ret = (xmlSchemaQNameRefPtr)
5335
0
  xmlMalloc(sizeof(xmlSchemaQNameRef));
5336
0
    if (ret == NULL) {
5337
0
  xmlSchemaPErrMemory(pctxt);
5338
0
  return (NULL);
5339
0
    }
5340
0
    ret->node = NULL;
5341
0
    ret->type = XML_SCHEMA_EXTRA_QNAMEREF;
5342
0
    ret->name = refName;
5343
0
    ret->targetNamespace = refNs;
5344
0
    ret->item = NULL;
5345
0
    ret->itemType = refType;
5346
    /*
5347
    * Store the reference item in the schema.
5348
    */
5349
0
    WXS_ADD_LOCAL(pctxt, ret);
5350
0
    return (ret);
5351
0
}
5352
5353
static xmlSchemaAttributeUseProhibPtr
5354
xmlSchemaAddAttributeUseProhib(xmlSchemaParserCtxtPtr pctxt)
5355
0
{
5356
0
    xmlSchemaAttributeUseProhibPtr ret;
5357
5358
0
    ret = (xmlSchemaAttributeUseProhibPtr)
5359
0
  xmlMalloc(sizeof(xmlSchemaAttributeUseProhib));
5360
0
    if (ret == NULL) {
5361
0
  xmlSchemaPErrMemory(pctxt);
5362
0
  return (NULL);
5363
0
    }
5364
0
    memset(ret, 0, sizeof(xmlSchemaAttributeUseProhib));
5365
0
    ret->type = XML_SCHEMA_EXTRA_ATTR_USE_PROHIB;
5366
0
    WXS_ADD_LOCAL(pctxt, ret);
5367
0
    return (ret);
5368
0
}
5369
5370
5371
/**
5372
 * xmlSchemaAddModelGroup:
5373
 * @ctxt:  a schema parser context
5374
 * @schema:  the schema being built
5375
 * @type: the "compositor" type of the model group
5376
 * @node: the node in the schema doc
5377
 *
5378
 * Adds a schema model group
5379
 * *WARNING* this interface is highly subject to change
5380
 *
5381
 * Returns the new structure or NULL in case of error
5382
 */
5383
static xmlSchemaModelGroupPtr
5384
xmlSchemaAddModelGroup(xmlSchemaParserCtxtPtr ctxt,
5385
           xmlSchemaPtr schema,
5386
           xmlSchemaTypeType type,
5387
           xmlNodePtr node)
5388
0
{
5389
0
    xmlSchemaModelGroupPtr ret = NULL;
5390
5391
0
    if ((ctxt == NULL) || (schema == NULL))
5392
0
        return (NULL);
5393
5394
0
    ret = (xmlSchemaModelGroupPtr)
5395
0
  xmlMalloc(sizeof(xmlSchemaModelGroup));
5396
0
    if (ret == NULL) {
5397
0
  xmlSchemaPErrMemory(ctxt);
5398
0
  return (NULL);
5399
0
    }
5400
0
    memset(ret, 0, sizeof(xmlSchemaModelGroup));
5401
0
    ret->type = type;
5402
0
    ret->node = node;
5403
0
    WXS_ADD_LOCAL(ctxt, ret);
5404
0
    if ((type == XML_SCHEMA_TYPE_SEQUENCE) ||
5405
0
  (type == XML_SCHEMA_TYPE_CHOICE))
5406
0
  WXS_ADD_PENDING(ctxt, ret);
5407
0
    return (ret);
5408
0
}
5409
5410
5411
/**
5412
 * xmlSchemaAddParticle:
5413
 * @ctxt:  a schema parser context
5414
 * @schema:  the schema being built
5415
 * @node: the corresponding node in the schema doc
5416
 * @min: the minOccurs
5417
 * @max: the maxOccurs
5418
 *
5419
 * Adds an XML schema particle component.
5420
 * *WARNING* this interface is highly subject to change
5421
 *
5422
 * Returns the new structure or NULL in case of error
5423
 */
5424
static xmlSchemaParticlePtr
5425
xmlSchemaAddParticle(xmlSchemaParserCtxtPtr ctxt,
5426
         xmlNodePtr node, int min, int max)
5427
0
{
5428
0
    xmlSchemaParticlePtr ret = NULL;
5429
0
    if (ctxt == NULL)
5430
0
        return (NULL);
5431
5432
0
    ret = (xmlSchemaParticlePtr)
5433
0
  xmlMalloc(sizeof(xmlSchemaParticle));
5434
0
    if (ret == NULL) {
5435
0
  xmlSchemaPErrMemory(ctxt);
5436
0
  return (NULL);
5437
0
    }
5438
0
    ret->type = XML_SCHEMA_TYPE_PARTICLE;
5439
0
    ret->annot = NULL;
5440
0
    ret->node = node;
5441
0
    ret->minOccurs = min;
5442
0
    ret->maxOccurs = max;
5443
0
    ret->next = NULL;
5444
0
    ret->children = NULL;
5445
5446
0
    WXS_ADD_LOCAL(ctxt, ret);
5447
    /*
5448
    * Note that addition to pending components will be done locally
5449
    * to the specific parsing function, since the most particles
5450
    * need not to be fixed up (i.e. the reference to be resolved).
5451
    * REMOVED: WXS_ADD_PENDING(ctxt, ret);
5452
    */
5453
0
    return (ret);
5454
0
}
5455
5456
/**
5457
 * xmlSchemaAddModelGroupDefinition:
5458
 * @ctxt:  a schema validation context
5459
 * @schema:  the schema being built
5460
 * @name:  the group name
5461
 *
5462
 * Add an XML schema Group definition
5463
 *
5464
 * Returns the new structure or NULL in case of error
5465
 */
5466
static xmlSchemaModelGroupDefPtr
5467
xmlSchemaAddModelGroupDefinition(xmlSchemaParserCtxtPtr ctxt,
5468
         xmlSchemaPtr schema,
5469
         const xmlChar *name,
5470
         const xmlChar *nsName,
5471
         xmlNodePtr node)
5472
0
{
5473
0
    xmlSchemaModelGroupDefPtr ret = NULL;
5474
5475
0
    if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
5476
0
        return (NULL);
5477
5478
0
    ret = (xmlSchemaModelGroupDefPtr)
5479
0
  xmlMalloc(sizeof(xmlSchemaModelGroupDef));
5480
0
    if (ret == NULL) {
5481
0
        xmlSchemaPErrMemory(ctxt);
5482
0
        return (NULL);
5483
0
    }
5484
0
    memset(ret, 0, sizeof(xmlSchemaModelGroupDef));
5485
0
    ret->name = name;
5486
0
    ret->type = XML_SCHEMA_TYPE_GROUP;
5487
0
    ret->node = node;
5488
0
    ret->targetNamespace = nsName;
5489
5490
0
    if (ctxt->isRedefine) {
5491
0
  ctxt->redef = xmlSchemaAddRedef(ctxt, ctxt->redefined,
5492
0
      ret, name, nsName);
5493
0
  if (ctxt->redef == NULL) {
5494
0
      xmlFree(ret);
5495
0
      return(NULL);
5496
0
  }
5497
0
  ctxt->redefCounter = 0;
5498
0
    }
5499
0
    WXS_ADD_GLOBAL(ctxt, ret);
5500
0
    WXS_ADD_PENDING(ctxt, ret);
5501
0
    return (ret);
5502
0
}
5503
5504
/**
5505
 * xmlSchemaNewWildcardNs:
5506
 * @ctxt:  a schema validation context
5507
 *
5508
 * Creates a new wildcard namespace constraint.
5509
 *
5510
 * Returns the new structure or NULL in case of error
5511
 */
5512
static xmlSchemaWildcardNsPtr
5513
xmlSchemaNewWildcardNsConstraint(xmlSchemaParserCtxtPtr ctxt)
5514
0
{
5515
0
    xmlSchemaWildcardNsPtr ret;
5516
5517
0
    ret = (xmlSchemaWildcardNsPtr)
5518
0
  xmlMalloc(sizeof(xmlSchemaWildcardNs));
5519
0
    if (ret == NULL) {
5520
0
  xmlSchemaPErrMemory(ctxt);
5521
0
  return (NULL);
5522
0
    }
5523
0
    ret->value = NULL;
5524
0
    ret->next = NULL;
5525
0
    return (ret);
5526
0
}
5527
5528
static xmlSchemaIDCPtr
5529
xmlSchemaAddIDC(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
5530
                  const xmlChar *name, const xmlChar *nsName,
5531
      int category, xmlNodePtr node)
5532
0
{
5533
0
    xmlSchemaIDCPtr ret = NULL;
5534
5535
0
    if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
5536
0
        return (NULL);
5537
5538
0
    ret = (xmlSchemaIDCPtr) xmlMalloc(sizeof(xmlSchemaIDC));
5539
0
    if (ret == NULL) {
5540
0
        xmlSchemaPErrMemory(ctxt);
5541
0
        return (NULL);
5542
0
    }
5543
0
    memset(ret, 0, sizeof(xmlSchemaIDC));
5544
    /* The target namespace of the parent element declaration. */
5545
0
    ret->targetNamespace = nsName;
5546
0
    ret->name = name;
5547
0
    ret->type = category;
5548
0
    ret->node = node;
5549
5550
0
    WXS_ADD_GLOBAL(ctxt, ret);
5551
    /*
5552
    * Only keyrefs need to be fixup up.
5553
    */
5554
0
    if (category == XML_SCHEMA_TYPE_IDC_KEYREF)
5555
0
  WXS_ADD_PENDING(ctxt, ret);
5556
0
    return (ret);
5557
0
}
5558
5559
/**
5560
 * xmlSchemaAddWildcard:
5561
 * @ctxt:  a schema validation context
5562
 * @schema: a schema
5563
 *
5564
 * Adds a wildcard.
5565
 * It corresponds to a xsd:anyAttribute and xsd:any.
5566
 *
5567
 * Returns the new structure or NULL in case of error
5568
 */
5569
static xmlSchemaWildcardPtr
5570
xmlSchemaAddWildcard(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
5571
         xmlSchemaTypeType type, xmlNodePtr node)
5572
0
{
5573
0
    xmlSchemaWildcardPtr ret = NULL;
5574
5575
0
    if ((ctxt == NULL) || (schema == NULL))
5576
0
        return (NULL);
5577
5578
0
    ret = (xmlSchemaWildcardPtr) xmlMalloc(sizeof(xmlSchemaWildcard));
5579
0
    if (ret == NULL) {
5580
0
        xmlSchemaPErrMemory(ctxt);
5581
0
        return (NULL);
5582
0
    }
5583
0
    memset(ret, 0, sizeof(xmlSchemaWildcard));
5584
0
    ret->type = type;
5585
0
    ret->node = node;
5586
0
    WXS_ADD_LOCAL(ctxt, ret);
5587
0
    return (ret);
5588
0
}
5589
5590
static void
5591
xmlSchemaSubstGroupFree(xmlSchemaSubstGroupPtr group)
5592
0
{
5593
0
    if (group == NULL)
5594
0
  return;
5595
0
    if (group->members != NULL)
5596
0
  xmlSchemaItemListFree(group->members);
5597
0
    xmlFree(group);
5598
0
}
5599
5600
static void
5601
xmlSchemaSubstGroupFreeEntry(void *group, const xmlChar *name ATTRIBUTE_UNUSED)
5602
0
{
5603
0
    xmlSchemaSubstGroupFree((xmlSchemaSubstGroupPtr) group);
5604
0
}
5605
5606
static xmlSchemaSubstGroupPtr
5607
xmlSchemaSubstGroupAdd(xmlSchemaParserCtxtPtr pctxt,
5608
           xmlSchemaElementPtr head)
5609
0
{
5610
0
    xmlSchemaSubstGroupPtr ret;
5611
5612
    /* Init subst group hash. */
5613
0
    if (WXS_SUBST_GROUPS(pctxt) == NULL) {
5614
0
  WXS_SUBST_GROUPS(pctxt) = xmlHashCreateDict(10, pctxt->dict);
5615
0
  if (WXS_SUBST_GROUPS(pctxt) == NULL)
5616
0
      return(NULL);
5617
0
    }
5618
    /* Create a new substitution group. */
5619
0
    ret = (xmlSchemaSubstGroupPtr) xmlMalloc(sizeof(xmlSchemaSubstGroup));
5620
0
    if (ret == NULL) {
5621
0
  xmlSchemaPErrMemory(NULL);
5622
0
  return(NULL);
5623
0
    }
5624
0
    memset(ret, 0, sizeof(xmlSchemaSubstGroup));
5625
0
    ret->head = head;
5626
    /* Create list of members. */
5627
0
    ret->members = xmlSchemaItemListCreate();
5628
0
    if (ret->members == NULL) {
5629
0
  xmlSchemaSubstGroupFree(ret);
5630
0
  return(NULL);
5631
0
    }
5632
    /* Add subst group to hash. */
5633
0
    if (xmlHashAddEntry2(WXS_SUBST_GROUPS(pctxt),
5634
0
  head->name, head->targetNamespace, ret) != 0) {
5635
0
  PERROR_INT("xmlSchemaSubstGroupAdd",
5636
0
      "failed to add a new substitution container");
5637
0
  xmlSchemaSubstGroupFree(ret);
5638
0
  return(NULL);
5639
0
    }
5640
0
    return(ret);
5641
0
}
5642
5643
static xmlSchemaSubstGroupPtr
5644
xmlSchemaSubstGroupGet(xmlSchemaParserCtxtPtr pctxt,
5645
           xmlSchemaElementPtr head)
5646
0
{
5647
0
    if (WXS_SUBST_GROUPS(pctxt) == NULL)
5648
0
  return(NULL);
5649
0
    return(xmlHashLookup2(WXS_SUBST_GROUPS(pctxt),
5650
0
  head->name, head->targetNamespace));
5651
5652
0
}
5653
5654
/**
5655
 * xmlSchemaAddElementSubstitutionMember:
5656
 * @pctxt:  a schema parser context
5657
 * @head:  the head of the substitution group
5658
 * @member: the new member of the substitution group
5659
 *
5660
 * Allocate a new annotation structure.
5661
 *
5662
 * Returns the newly allocated structure or NULL in case or error
5663
 */
5664
static int
5665
xmlSchemaAddElementSubstitutionMember(xmlSchemaParserCtxtPtr pctxt,
5666
              xmlSchemaElementPtr head,
5667
              xmlSchemaElementPtr member)
5668
0
{
5669
0
    xmlSchemaSubstGroupPtr substGroup = NULL;
5670
5671
0
    if ((pctxt == NULL) || (head == NULL) || (member == NULL))
5672
0
  return (-1);
5673
5674
0
    substGroup = xmlSchemaSubstGroupGet(pctxt, head);
5675
0
    if (substGroup == NULL)
5676
0
  substGroup = xmlSchemaSubstGroupAdd(pctxt, head);
5677
0
    if (substGroup == NULL)
5678
0
  return(-1);
5679
0
    if (xmlSchemaItemListAdd(substGroup->members, member) == -1)
5680
0
  return(-1);
5681
0
    return(0);
5682
0
}
5683
5684
/************************************************************************
5685
 *                  *
5686
 *    Utilities for parsing         *
5687
 *                  *
5688
 ************************************************************************/
5689
5690
/**
5691
 * xmlSchemaPValAttrNodeQNameValue:
5692
 * @ctxt:  a schema parser context
5693
 * @schema: the schema context
5694
 * @ownerItem: the parent as a schema object
5695
 * @value:  the QName value
5696
 * @uri:  the resulting namespace URI if found
5697
 * @local: the resulting local part if found, the attribute value otherwise
5698
 *
5699
 * Extracts the local name and the URI of a QName value and validates it.
5700
 * This one is intended to be used on attribute values that
5701
 * should resolve to schema components.
5702
 *
5703
 * Returns 0, in case the QName is valid, a positive error code
5704
 * if not valid and -1 if an internal error occurs.
5705
 */
5706
static int
5707
xmlSchemaPValAttrNodeQNameValue(xmlSchemaParserCtxtPtr ctxt,
5708
               xmlSchemaPtr schema,
5709
               xmlSchemaBasicItemPtr ownerItem,
5710
               xmlAttrPtr attr,
5711
               const xmlChar *value,
5712
               const xmlChar **uri,
5713
               const xmlChar **local)
5714
0
{
5715
0
    const xmlChar *pref;
5716
0
    xmlNsPtr ns;
5717
0
    int len, ret;
5718
5719
0
    *uri = NULL;
5720
0
    *local = NULL;
5721
0
    ret = xmlValidateQName(value, 1);
5722
0
    if (ret > 0) {
5723
0
  xmlSchemaPSimpleTypeErr(ctxt,
5724
0
      XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
5725
0
      ownerItem, (xmlNodePtr) attr,
5726
0
      xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
5727
0
      NULL, value, NULL, NULL, NULL);
5728
0
  *local = value;
5729
0
  return (ctxt->err);
5730
0
    } else if (ret < 0)
5731
0
  return (-1);
5732
5733
0
    if (!strchr((char *) value, ':')) {
5734
0
  ns = xmlSearchNs(attr->doc, attr->parent, NULL);
5735
0
  if (ns && ns->href && ns->href[0])
5736
0
      *uri = xmlDictLookup(ctxt->dict, ns->href, -1);
5737
0
  else if (schema->flags & XML_SCHEMAS_INCLUDING_CONVERT_NS) {
5738
      /* TODO: move XML_SCHEMAS_INCLUDING_CONVERT_NS to the
5739
      * parser context. */
5740
      /*
5741
      * This one takes care of included schemas with no
5742
      * target namespace.
5743
      */
5744
0
      *uri = ctxt->targetNamespace;
5745
0
  }
5746
0
  *local = xmlDictLookup(ctxt->dict, value, -1);
5747
0
  return (0);
5748
0
    }
5749
    /*
5750
    * At this point xmlSplitQName3 has to return a local name.
5751
    */
5752
0
    *local = xmlSplitQName3(value, &len);
5753
0
    *local = xmlDictLookup(ctxt->dict, *local, -1);
5754
0
    pref = xmlDictLookup(ctxt->dict, value, len);
5755
0
    ns = xmlSearchNs(attr->doc, attr->parent, pref);
5756
0
    if (ns == NULL) {
5757
0
  xmlSchemaPSimpleTypeErr(ctxt,
5758
0
      XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
5759
0
      ownerItem, (xmlNodePtr) attr,
5760
0
      xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), NULL, value,
5761
0
      "The value '%s' of simple type 'xs:QName' has no "
5762
0
      "corresponding namespace declaration in scope", value, NULL);
5763
0
  return (ctxt->err);
5764
0
    } else {
5765
0
        *uri = xmlDictLookup(ctxt->dict, ns->href, -1);
5766
0
    }
5767
0
    return (0);
5768
0
}
5769
5770
/**
5771
 * xmlSchemaPValAttrNodeQName:
5772
 * @ctxt:  a schema parser context
5773
 * @schema: the schema context
5774
 * @ownerItem: the owner as a schema object
5775
 * @attr:  the attribute node
5776
 * @uri:  the resulting namespace URI if found
5777
 * @local: the resulting local part if found, the attribute value otherwise
5778
 *
5779
 * Extracts and validates the QName of an attribute value.
5780
 * This one is intended to be used on attribute values that
5781
 * should resolve to schema components.
5782
 *
5783
 * Returns 0, in case the QName is valid, a positive error code
5784
 * if not valid and -1 if an internal error occurs.
5785
 */
5786
static int
5787
xmlSchemaPValAttrNodeQName(xmlSchemaParserCtxtPtr ctxt,
5788
               xmlSchemaPtr schema,
5789
               xmlSchemaBasicItemPtr ownerItem,
5790
               xmlAttrPtr attr,
5791
               const xmlChar **uri,
5792
               const xmlChar **local)
5793
0
{
5794
0
    const xmlChar *value;
5795
5796
0
    value = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
5797
0
    return (xmlSchemaPValAttrNodeQNameValue(ctxt, schema,
5798
0
  ownerItem, attr, value, uri, local));
5799
0
}
5800
5801
/**
5802
 * xmlSchemaPValAttrQName:
5803
 * @ctxt:  a schema parser context
5804
 * @schema: the schema context
5805
 * @ownerItem: the owner as a schema object
5806
 * @ownerElem:  the parent node of the attribute
5807
 * @name:  the name of the attribute
5808
 * @uri:  the resulting namespace URI if found
5809
 * @local: the resulting local part if found, the attribute value otherwise
5810
 *
5811
 * Extracts and validates the QName of an attribute value.
5812
 *
5813
 * Returns 0, in case the QName is valid, a positive error code
5814
 * if not valid and -1 if an internal error occurs.
5815
 */
5816
static int
5817
xmlSchemaPValAttrQName(xmlSchemaParserCtxtPtr ctxt,
5818
           xmlSchemaPtr schema,
5819
           xmlSchemaBasicItemPtr ownerItem,
5820
           xmlNodePtr ownerElem,
5821
           const char *name,
5822
           const xmlChar **uri,
5823
           const xmlChar **local)
5824
0
{
5825
0
    xmlAttrPtr attr;
5826
5827
0
    attr = xmlSchemaGetPropNode(ownerElem, name);
5828
0
    if (attr == NULL) {
5829
0
  *local = NULL;
5830
0
  *uri = NULL;
5831
0
  return (0);
5832
0
    }
5833
0
    return (xmlSchemaPValAttrNodeQName(ctxt, schema,
5834
0
  ownerItem, attr, uri, local));
5835
0
}
5836
5837
/**
5838
 * xmlSchemaPValAttrID:
5839
 * @ctxt:  a schema parser context
5840
 *
5841
 * Extracts and validates the ID of an attribute value.
5842
 *
5843
 * Returns 0, in case the ID is valid, a positive error code
5844
 * if not valid and -1 if an internal error occurs.
5845
 */
5846
static int
5847
xmlSchemaPValAttrNodeID(xmlSchemaParserCtxtPtr ctxt, xmlAttrPtr attr)
5848
0
{
5849
0
    int ret;
5850
0
    const xmlChar *value;
5851
5852
0
    if (attr == NULL)
5853
0
  return(0);
5854
0
    value = xmlSchemaGetNodeContentNoDict((xmlNodePtr) attr);
5855
0
    ret = xmlValidateNCName(value, 1);
5856
0
    if (ret == 0) {
5857
  /*
5858
  * NOTE: the IDness might have already be declared in the DTD
5859
  */
5860
0
  if (attr->atype != XML_ATTRIBUTE_ID) {
5861
0
      xmlChar *strip;
5862
0
            int res;
5863
5864
      /*
5865
      * TODO: Use xmlSchemaStrip here; it's not exported at this
5866
      * moment.
5867
      */
5868
0
      strip = xmlSchemaCollapseString(value);
5869
0
      if (strip != NULL) {
5870
0
    xmlFree((xmlChar *) value);
5871
0
    value = strip;
5872
0
      }
5873
0
      res = xmlAddIDSafe(attr, value);
5874
0
            if (res < 0) {
5875
0
                xmlSchemaPErrMemory(ctxt);
5876
0
      } else if (res == 0) {
5877
0
    ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
5878
0
    xmlSchemaPSimpleTypeErr(ctxt,
5879
0
        XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
5880
0
        NULL, (xmlNodePtr) attr,
5881
0
        xmlSchemaGetBuiltInType(XML_SCHEMAS_ID),
5882
0
        NULL, NULL, "Duplicate value '%s' of simple "
5883
0
        "type 'xs:ID'", value, NULL);
5884
0
      }
5885
0
  }
5886
0
    } else if (ret > 0) {
5887
0
  ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
5888
0
  xmlSchemaPSimpleTypeErr(ctxt,
5889
0
      XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
5890
0
      NULL, (xmlNodePtr) attr,
5891
0
      xmlSchemaGetBuiltInType(XML_SCHEMAS_ID),
5892
0
      NULL, NULL, "The value '%s' of simple type 'xs:ID' is "
5893
0
      "not a valid 'xs:NCName'",
5894
0
      value, NULL);
5895
0
    }
5896
0
    if (value != NULL)
5897
0
  xmlFree((xmlChar *)value);
5898
5899
0
    return (ret);
5900
0
}
5901
5902
static int
5903
xmlSchemaPValAttrID(xmlSchemaParserCtxtPtr ctxt,
5904
        xmlNodePtr ownerElem,
5905
        const xmlChar *name)
5906
0
{
5907
0
    xmlAttrPtr attr;
5908
5909
0
    attr = xmlSchemaGetPropNode(ownerElem, (const char *) name);
5910
0
    if (attr == NULL)
5911
0
  return(0);
5912
0
    return(xmlSchemaPValAttrNodeID(ctxt, attr));
5913
5914
0
}
5915
5916
/**
5917
 * xmlGetMaxOccurs:
5918
 * @ctxt:  a schema validation context
5919
 * @node:  a subtree containing XML Schema information
5920
 *
5921
 * Get the maxOccurs property
5922
 *
5923
 * Returns the default if not found, or the value
5924
 */
5925
static int
5926
xmlGetMaxOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
5927
    int min, int max, int def, const char *expected)
5928
0
{
5929
0
    const xmlChar *val, *cur;
5930
0
    int ret = 0;
5931
0
    xmlAttrPtr attr;
5932
5933
0
    attr = xmlSchemaGetPropNode(node, "maxOccurs");
5934
0
    if (attr == NULL)
5935
0
  return (def);
5936
0
    val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
5937
0
    if (val == NULL)
5938
0
        return (def);
5939
5940
0
    if (xmlStrEqual(val, (const xmlChar *) "unbounded")) {
5941
0
  if (max != UNBOUNDED) {
5942
0
      xmlSchemaPSimpleTypeErr(ctxt,
5943
0
    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
5944
    /* XML_SCHEMAP_INVALID_MINOCCURS, */
5945
0
    NULL, (xmlNodePtr) attr, NULL, expected,
5946
0
    val, NULL, NULL, NULL);
5947
0
      return (def);
5948
0
  } else
5949
0
      return (UNBOUNDED);  /* encoding it with -1 might be another option */
5950
0
    }
5951
5952
0
    cur = val;
5953
0
    while (IS_BLANK_CH(*cur))
5954
0
        cur++;
5955
0
    if (*cur == 0) {
5956
0
        xmlSchemaPSimpleTypeErr(ctxt,
5957
0
      XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
5958
      /* XML_SCHEMAP_INVALID_MINOCCURS, */
5959
0
      NULL, (xmlNodePtr) attr, NULL, expected,
5960
0
      val, NULL, NULL, NULL);
5961
0
  return (def);
5962
0
    }
5963
0
    while ((*cur >= '0') && (*cur <= '9')) {
5964
0
        if (ret > INT_MAX / 10) {
5965
0
            ret = INT_MAX;
5966
0
        } else {
5967
0
            int digit = *cur - '0';
5968
0
            ret *= 10;
5969
0
            if (ret > INT_MAX - digit)
5970
0
                ret = INT_MAX;
5971
0
            else
5972
0
                ret += digit;
5973
0
        }
5974
0
        cur++;
5975
0
    }
5976
0
    while (IS_BLANK_CH(*cur))
5977
0
        cur++;
5978
    /*
5979
    * TODO: Restrict the maximal value to Integer.
5980
    */
5981
0
    if ((*cur != 0) || (ret < min) || ((max != -1) && (ret > max))) {
5982
0
  xmlSchemaPSimpleTypeErr(ctxt,
5983
0
      XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
5984
      /* XML_SCHEMAP_INVALID_MINOCCURS, */
5985
0
      NULL, (xmlNodePtr) attr, NULL, expected,
5986
0
      val, NULL, NULL, NULL);
5987
0
        return (def);
5988
0
    }
5989
0
    return (ret);
5990
0
}
5991
5992
/**
5993
 * xmlGetMinOccurs:
5994
 * @ctxt:  a schema validation context
5995
 * @node:  a subtree containing XML Schema information
5996
 *
5997
 * Get the minOccurs property
5998
 *
5999
 * Returns the default if not found, or the value
6000
 */
6001
static int
6002
xmlGetMinOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
6003
    int min, int max, int def, const char *expected)
6004
0
{
6005
0
    const xmlChar *val, *cur;
6006
0
    int ret = 0;
6007
0
    xmlAttrPtr attr;
6008
6009
0
    attr = xmlSchemaGetPropNode(node, "minOccurs");
6010
0
    if (attr == NULL)
6011
0
  return (def);
6012
0
    val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
6013
0
    if (val == NULL)
6014
0
  return (def);
6015
0
    cur = val;
6016
0
    while (IS_BLANK_CH(*cur))
6017
0
        cur++;
6018
0
    if (*cur == 0) {
6019
0
        xmlSchemaPSimpleTypeErr(ctxt,
6020
0
      XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
6021
      /* XML_SCHEMAP_INVALID_MINOCCURS, */
6022
0
      NULL, (xmlNodePtr) attr, NULL, expected,
6023
0
      val, NULL, NULL, NULL);
6024
0
        return (def);
6025
0
    }
6026
0
    while ((*cur >= '0') && (*cur <= '9')) {
6027
0
        if (ret > INT_MAX / 10) {
6028
0
            ret = INT_MAX;
6029
0
        } else {
6030
0
            int digit = *cur - '0';
6031
0
            ret *= 10;
6032
0
            if (ret > INT_MAX - digit)
6033
0
                ret = INT_MAX;
6034
0
            else
6035
0
                ret += digit;
6036
0
        }
6037
0
        cur++;
6038
0
    }
6039
0
    while (IS_BLANK_CH(*cur))
6040
0
        cur++;
6041
    /*
6042
    * TODO: Restrict the maximal value to Integer.
6043
    */
6044
0
    if ((*cur != 0) || (ret < min) || ((max != -1) && (ret > max))) {
6045
0
  xmlSchemaPSimpleTypeErr(ctxt,
6046
0
      XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
6047
      /* XML_SCHEMAP_INVALID_MINOCCURS, */
6048
0
      NULL, (xmlNodePtr) attr, NULL, expected,
6049
0
      val, NULL, NULL, NULL);
6050
0
        return (def);
6051
0
    }
6052
0
    return (ret);
6053
0
}
6054
6055
/**
6056
 * xmlSchemaPGetBoolNodeValue:
6057
 * @ctxt:  a schema validation context
6058
 * @ownerItem:  the owner as a schema item
6059
 * @node: the node holding the value
6060
 *
6061
 * Converts a boolean string value into 1 or 0.
6062
 *
6063
 * Returns 0 or 1.
6064
 */
6065
static int
6066
xmlSchemaPGetBoolNodeValue(xmlSchemaParserCtxtPtr ctxt,
6067
         xmlSchemaBasicItemPtr ownerItem,
6068
         xmlNodePtr node)
6069
0
{
6070
0
    xmlChar *value = NULL;
6071
0
    int res = 0;
6072
6073
0
    value = xmlNodeGetContent(node);
6074
    /*
6075
    * 3.2.2.1 Lexical representation
6076
    * An instance of a datatype that is defined as `boolean`
6077
    * can have the following legal literals {true, false, 1, 0}.
6078
    */
6079
0
    if (xmlStrEqual(BAD_CAST value, BAD_CAST "true"))
6080
0
        res = 1;
6081
0
    else if (xmlStrEqual(BAD_CAST value, BAD_CAST "false"))
6082
0
        res = 0;
6083
0
    else if (xmlStrEqual(BAD_CAST value, BAD_CAST "1"))
6084
0
  res = 1;
6085
0
    else if (xmlStrEqual(BAD_CAST value, BAD_CAST "0"))
6086
0
        res = 0;
6087
0
    else {
6088
0
        xmlSchemaPSimpleTypeErr(ctxt,
6089
0
      XML_SCHEMAP_INVALID_BOOLEAN,
6090
0
      ownerItem, node,
6091
0
      xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN),
6092
0
      NULL, BAD_CAST value,
6093
0
      NULL, NULL, NULL);
6094
0
    }
6095
0
    if (value != NULL)
6096
0
  xmlFree(value);
6097
0
    return (res);
6098
0
}
6099
6100
/**
6101
 * xmlGetBooleanProp:
6102
 * @ctxt:  a schema validation context
6103
 * @node:  a subtree containing XML Schema information
6104
 * @name:  the attribute name
6105
 * @def:  the default value
6106
 *
6107
 * Evaluate if a boolean property is set
6108
 *
6109
 * Returns the default if not found, 0 if found to be false,
6110
 * 1 if found to be true
6111
 */
6112
static int
6113
xmlGetBooleanProp(xmlSchemaParserCtxtPtr ctxt,
6114
      xmlNodePtr node,
6115
                  const char *name, int def)
6116
0
{
6117
0
    const xmlChar *val;
6118
6119
0
    val = xmlSchemaGetProp(ctxt, node, name);
6120
0
    if (val == NULL)
6121
0
        return (def);
6122
    /*
6123
    * 3.2.2.1 Lexical representation
6124
    * An instance of a datatype that is defined as `boolean`
6125
    * can have the following legal literals {true, false, 1, 0}.
6126
    */
6127
0
    if (xmlStrEqual(val, BAD_CAST "true"))
6128
0
        def = 1;
6129
0
    else if (xmlStrEqual(val, BAD_CAST "false"))
6130
0
        def = 0;
6131
0
    else if (xmlStrEqual(val, BAD_CAST "1"))
6132
0
  def = 1;
6133
0
    else if (xmlStrEqual(val, BAD_CAST "0"))
6134
0
        def = 0;
6135
0
    else {
6136
0
        xmlSchemaPSimpleTypeErr(ctxt,
6137
0
      XML_SCHEMAP_INVALID_BOOLEAN,
6138
0
      NULL,
6139
0
      (xmlNodePtr) xmlSchemaGetPropNode(node, name),
6140
0
      xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN),
6141
0
      NULL, val, NULL, NULL, NULL);
6142
0
    }
6143
0
    return (def);
6144
0
}
6145
6146
/************************************************************************
6147
 *                  *
6148
 *    Schema extraction from an Infoset     *
6149
 *                  *
6150
 ************************************************************************/
6151
static xmlSchemaTypePtr xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr
6152
                                                 ctxt, xmlSchemaPtr schema,
6153
                                                 xmlNodePtr node,
6154
             int topLevel);
6155
static xmlSchemaTypePtr xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr
6156
                                                  ctxt,
6157
                                                  xmlSchemaPtr schema,
6158
                                                  xmlNodePtr node,
6159
              int topLevel);
6160
static xmlSchemaTypePtr xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr
6161
                                                  ctxt,
6162
                                                  xmlSchemaPtr schema,
6163
                                                  xmlNodePtr node,
6164
              xmlSchemaTypeType parentType);
6165
static xmlSchemaBasicItemPtr
6166
xmlSchemaParseLocalAttribute(xmlSchemaParserCtxtPtr pctxt,
6167
           xmlSchemaPtr schema,
6168
           xmlNodePtr node,
6169
           xmlSchemaItemListPtr uses,
6170
           int parentType);
6171
static xmlSchemaTypePtr xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt,
6172
                                           xmlSchemaPtr schema,
6173
                                           xmlNodePtr node);
6174
static xmlSchemaWildcardPtr
6175
xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt,
6176
                           xmlSchemaPtr schema, xmlNodePtr node);
6177
6178
/**
6179
 * xmlSchemaPValAttrNodeValue:
6180
 *
6181
 * @pctxt:  a schema parser context
6182
 * @ownerItem: the schema object owner if existent
6183
 * @attr:  the schema attribute node being validated
6184
 * @value: the value
6185
 * @type: the built-in type to be validated against
6186
 *
6187
 * Validates a value against the given built-in type.
6188
 * This one is intended to be used internally for validation
6189
 * of schema attribute values during parsing of the schema.
6190
 *
6191
 * Returns 0 if the value is valid, a positive error code
6192
 * number otherwise and -1 in case of an internal or API error.
6193
 */
6194
static int
6195
xmlSchemaPValAttrNodeValue(xmlSchemaParserCtxtPtr pctxt,
6196
         xmlSchemaBasicItemPtr ownerItem,
6197
         xmlAttrPtr attr,
6198
         const xmlChar *value,
6199
         xmlSchemaTypePtr type)
6200
0
{
6201
6202
0
    int ret = 0;
6203
6204
    /*
6205
    * NOTE: Should we move this to xmlschematypes.c? Hmm, but this
6206
    * one is really meant to be used internally, so better not.
6207
    */
6208
0
    if ((pctxt == NULL) || (type == NULL) || (attr == NULL))
6209
0
  return (-1);
6210
0
    if (type->type != XML_SCHEMA_TYPE_BASIC) {
6211
0
  PERROR_INT("xmlSchemaPValAttrNodeValue",
6212
0
      "the given type is not a built-in type");
6213
0
  return (-1);
6214
0
    }
6215
0
    switch (type->builtInType) {
6216
0
  case XML_SCHEMAS_NCNAME:
6217
0
  case XML_SCHEMAS_QNAME:
6218
0
  case XML_SCHEMAS_ANYURI:
6219
0
  case XML_SCHEMAS_TOKEN:
6220
0
  case XML_SCHEMAS_LANGUAGE:
6221
0
      ret = xmlSchemaValPredefTypeNode(type, value, NULL,
6222
0
    (xmlNodePtr) attr);
6223
0
      break;
6224
0
  default: {
6225
0
      PERROR_INT("xmlSchemaPValAttrNodeValue",
6226
0
    "validation using the given type is not supported while "
6227
0
    "parsing a schema");
6228
0
      return (-1);
6229
0
  }
6230
0
    }
6231
    /*
6232
    * TODO: Should we use the S4S error codes instead?
6233
    */
6234
0
    if (ret < 0) {
6235
0
  PERROR_INT("xmlSchemaPValAttrNodeValue",
6236
0
      "failed to validate a schema attribute value");
6237
0
  return (-1);
6238
0
    } else if (ret > 0) {
6239
0
  if (WXS_IS_LIST(type))
6240
0
      ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
6241
0
  else
6242
0
      ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
6243
0
  xmlSchemaPSimpleTypeErr(pctxt,
6244
0
      ret, ownerItem, (xmlNodePtr) attr,
6245
0
      type, NULL, value, NULL, NULL, NULL);
6246
0
    }
6247
0
    return (ret);
6248
0
}
6249
6250
/**
6251
 * xmlSchemaPValAttrNode:
6252
 *
6253
 * @ctxt:  a schema parser context
6254
 * @ownerItem: the schema object owner if existent
6255
 * @attr:  the schema attribute node being validated
6256
 * @type: the built-in type to be validated against
6257
 * @value: the resulting value if any
6258
 *
6259
 * Extracts and validates a value against the given built-in type.
6260
 * This one is intended to be used internally for validation
6261
 * of schema attribute values during parsing of the schema.
6262
 *
6263
 * Returns 0 if the value is valid, a positive error code
6264
 * number otherwise and -1 in case of an internal or API error.
6265
 */
6266
static int
6267
xmlSchemaPValAttrNode(xmlSchemaParserCtxtPtr ctxt,
6268
         xmlSchemaBasicItemPtr ownerItem,
6269
         xmlAttrPtr attr,
6270
         xmlSchemaTypePtr type,
6271
         const xmlChar **value)
6272
0
{
6273
0
    const xmlChar *val;
6274
6275
0
    if ((ctxt == NULL) || (type == NULL) || (attr == NULL))
6276
0
  return (-1);
6277
6278
0
    val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
6279
0
    if (value != NULL)
6280
0
  *value = val;
6281
6282
0
    return (xmlSchemaPValAttrNodeValue(ctxt, ownerItem, attr,
6283
0
  val, type));
6284
0
}
6285
6286
/**
6287
 * xmlSchemaPValAttr:
6288
 *
6289
 * @ctxt:  a schema parser context
6290
 * @node: the element node of the attribute
6291
 * @ownerItem: the schema object owner if existent
6292
 * @ownerElem: the owner element node
6293
 * @name:  the name of the schema attribute node
6294
 * @type: the built-in type to be validated against
6295
 * @value: the resulting value if any
6296
 *
6297
 * Extracts and validates a value against the given built-in type.
6298
 * This one is intended to be used internally for validation
6299
 * of schema attribute values during parsing of the schema.
6300
 *
6301
 * Returns 0 if the value is valid, a positive error code
6302
 * number otherwise and -1 in case of an internal or API error.
6303
 */
6304
static int
6305
xmlSchemaPValAttr(xmlSchemaParserCtxtPtr ctxt,
6306
           xmlSchemaBasicItemPtr ownerItem,
6307
           xmlNodePtr ownerElem,
6308
           const char *name,
6309
           xmlSchemaTypePtr type,
6310
           const xmlChar **value)
6311
0
{
6312
0
    xmlAttrPtr attr;
6313
6314
0
    if ((ctxt == NULL) || (type == NULL)) {
6315
0
  if (value != NULL)
6316
0
      *value = NULL;
6317
0
  return (-1);
6318
0
    }
6319
0
    if (type->type != XML_SCHEMA_TYPE_BASIC) {
6320
0
  if (value != NULL)
6321
0
      *value = NULL;
6322
0
  xmlSchemaPErr(ctxt, ownerElem,
6323
0
      XML_SCHEMAP_INTERNAL,
6324
0
      "Internal error: xmlSchemaPValAttr, the given "
6325
0
      "type '%s' is not a built-in type.\n",
6326
0
      type->name, NULL);
6327
0
  return (-1);
6328
0
    }
6329
0
    attr = xmlSchemaGetPropNode(ownerElem, name);
6330
0
    if (attr == NULL) {
6331
0
  if (value != NULL)
6332
0
      *value = NULL;
6333
0
  return (0);
6334
0
    }
6335
0
    return (xmlSchemaPValAttrNode(ctxt, ownerItem, attr,
6336
0
  type, value));
6337
0
}
6338
6339
static int
6340
xmlSchemaCheckReference(xmlSchemaParserCtxtPtr pctxt,
6341
      xmlSchemaPtr schema ATTRIBUTE_UNUSED,
6342
      xmlNodePtr node,
6343
      xmlAttrPtr attr,
6344
      const xmlChar *namespaceName)
6345
0
{
6346
    /* TODO: Pointer comparison instead? */
6347
0
    if (xmlStrEqual(pctxt->targetNamespace, namespaceName))
6348
0
  return (0);
6349
0
    if (xmlStrEqual(xmlSchemaNs, namespaceName))
6350
0
  return (0);
6351
    /*
6352
    * Check if the referenced namespace was <import>ed.
6353
    */
6354
0
    if (WXS_BUCKET(pctxt)->relations != NULL) {
6355
0
  xmlSchemaSchemaRelationPtr rel;
6356
6357
0
  rel = WXS_BUCKET(pctxt)->relations;
6358
0
  do {
6359
0
      if (WXS_IS_BUCKET_IMPMAIN(rel->type) &&
6360
0
    xmlStrEqual(namespaceName, rel->importNamespace))
6361
0
    return (0);
6362
0
      rel = rel->next;
6363
0
  } while (rel != NULL);
6364
0
    }
6365
    /*
6366
    * No matching <import>ed namespace found.
6367
    */
6368
0
    {
6369
0
  xmlNodePtr n = (attr != NULL) ? (xmlNodePtr) attr : node;
6370
6371
0
  if (namespaceName == NULL)
6372
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
6373
0
    XML_SCHEMAP_SRC_RESOLVE, n, NULL,
6374
0
    "References from this schema to components in no "
6375
0
    "namespace are not allowed, since not indicated by an "
6376
0
    "import statement", NULL, NULL);
6377
0
  else
6378
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
6379
0
    XML_SCHEMAP_SRC_RESOLVE, n, NULL,
6380
0
    "References from this schema to components in the "
6381
0
    "namespace '%s' are not allowed, since not indicated by an "
6382
0
    "import statement", namespaceName, NULL);
6383
0
    }
6384
0
    return (XML_SCHEMAP_SRC_RESOLVE);
6385
0
}
6386
6387
/**
6388
 * xmlSchemaParseLocalAttributes:
6389
 * @ctxt:  a schema validation context
6390
 * @schema:  the schema being built
6391
 * @node:  a subtree containing XML Schema information
6392
 * @type:  the hosting type where the attributes will be anchored
6393
 *
6394
 * Parses attribute uses and attribute declarations and
6395
 * attribute group references.
6396
 */
6397
static int
6398
xmlSchemaParseLocalAttributes(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
6399
                        xmlNodePtr *child, xmlSchemaItemListPtr *list,
6400
      int parentType, int *hasRefs)
6401
0
{
6402
0
    void *item;
6403
6404
0
    while ((IS_SCHEMA((*child), "attribute")) ||
6405
0
           (IS_SCHEMA((*child), "attributeGroup"))) {
6406
0
        if (IS_SCHEMA((*child), "attribute")) {
6407
0
      item = xmlSchemaParseLocalAttribute(ctxt, schema, *child,
6408
0
    *list, parentType);
6409
0
        } else {
6410
0
            item = xmlSchemaParseAttributeGroupRef(ctxt, schema, *child);
6411
0
      if ((item != NULL) && (hasRefs != NULL))
6412
0
    *hasRefs = 1;
6413
0
        }
6414
0
  if (item != NULL) {
6415
0
      if (*list == NULL) {
6416
    /* TODO: Customize grow factor. */
6417
0
    *list = xmlSchemaItemListCreate();
6418
0
    if (*list == NULL)
6419
0
        return(-1);
6420
0
      }
6421
0
      if (xmlSchemaItemListAddSize(*list, 2, item) == -1)
6422
0
    return(-1);
6423
0
  }
6424
0
        *child = (*child)->next;
6425
0
    }
6426
0
    return (0);
6427
0
}
6428
6429
/**
6430
 * xmlSchemaParseAnnotation:
6431
 * @ctxt:  a schema validation context
6432
 * @schema:  the schema being built
6433
 * @node:  a subtree containing XML Schema information
6434
 *
6435
 * parse a XML schema Attribute declaration
6436
 * *WARNING* this interface is highly subject to change
6437
 *
6438
 * Returns -1 in case of error, 0 if the declaration is improper and
6439
 *         1 in case of success.
6440
 */
6441
static xmlSchemaAnnotPtr
6442
xmlSchemaParseAnnotation(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int needed)
6443
0
{
6444
0
    xmlSchemaAnnotPtr ret;
6445
0
    xmlNodePtr child = NULL;
6446
0
    xmlAttrPtr attr;
6447
0
    int barked = 0;
6448
6449
    /*
6450
    * INFO: S4S completed.
6451
    */
6452
    /*
6453
    * id = ID
6454
    * {any attributes with non-schema namespace . . .}>
6455
    * Content: (appinfo | documentation)*
6456
    */
6457
0
    if ((ctxt == NULL) || (node == NULL))
6458
0
        return (NULL);
6459
0
    if (needed)
6460
0
  ret = xmlSchemaNewAnnot(ctxt, node);
6461
0
    else
6462
0
  ret = NULL;
6463
0
    attr = node->properties;
6464
0
    while (attr != NULL) {
6465
0
  if (((attr->ns == NULL) &&
6466
0
      (!xmlStrEqual(attr->name, BAD_CAST "id"))) ||
6467
0
      ((attr->ns != NULL) &&
6468
0
      xmlStrEqual(attr->ns->href, xmlSchemaNs))) {
6469
6470
0
      xmlSchemaPIllegalAttrErr(ctxt,
6471
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
6472
0
  }
6473
0
  attr = attr->next;
6474
0
    }
6475
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
6476
    /*
6477
    * And now for the children...
6478
    */
6479
0
    child = node->children;
6480
0
    while (child != NULL) {
6481
0
  if (IS_SCHEMA(child, "appinfo")) {
6482
      /* TODO: make available the content of "appinfo". */
6483
      /*
6484
      * source = anyURI
6485
      * {any attributes with non-schema namespace . . .}>
6486
      * Content: ({any})*
6487
      */
6488
0
      attr = child->properties;
6489
0
      while (attr != NULL) {
6490
0
    if (((attr->ns == NULL) &&
6491
0
         (!xmlStrEqual(attr->name, BAD_CAST "source"))) ||
6492
0
         ((attr->ns != NULL) &&
6493
0
          xmlStrEqual(attr->ns->href, xmlSchemaNs))) {
6494
6495
0
        xmlSchemaPIllegalAttrErr(ctxt,
6496
0
      XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
6497
0
    }
6498
0
    attr = attr->next;
6499
0
      }
6500
0
      xmlSchemaPValAttr(ctxt, NULL, child, "source",
6501
0
    xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), NULL);
6502
0
      child = child->next;
6503
0
  } else if (IS_SCHEMA(child, "documentation")) {
6504
      /* TODO: make available the content of "documentation". */
6505
      /*
6506
      * source = anyURI
6507
      * {any attributes with non-schema namespace . . .}>
6508
      * Content: ({any})*
6509
      */
6510
0
      attr = child->properties;
6511
0
      while (attr != NULL) {
6512
0
    if (attr->ns == NULL) {
6513
0
        if (!xmlStrEqual(attr->name, BAD_CAST "source")) {
6514
0
      xmlSchemaPIllegalAttrErr(ctxt,
6515
0
          XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
6516
0
        }
6517
0
    } else {
6518
0
        if (xmlStrEqual(attr->ns->href, xmlSchemaNs) ||
6519
0
      (xmlStrEqual(attr->name, BAD_CAST "lang") &&
6520
0
      (!xmlStrEqual(attr->ns->href, XML_XML_NAMESPACE)))) {
6521
6522
0
      xmlSchemaPIllegalAttrErr(ctxt,
6523
0
          XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
6524
0
        }
6525
0
    }
6526
0
    attr = attr->next;
6527
0
      }
6528
      /*
6529
      * Attribute "xml:lang".
6530
      */
6531
0
      attr = xmlSchemaGetPropNodeNs(child, (const char *) XML_XML_NAMESPACE, "lang");
6532
0
      if (attr != NULL)
6533
0
    xmlSchemaPValAttrNode(ctxt, NULL, attr,
6534
0
    xmlSchemaGetBuiltInType(XML_SCHEMAS_LANGUAGE), NULL);
6535
0
      child = child->next;
6536
0
  } else {
6537
0
      if (!barked)
6538
0
    xmlSchemaPContentErr(ctxt,
6539
0
        XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
6540
0
        NULL, node, child, NULL, "(appinfo | documentation)*");
6541
0
      barked = 1;
6542
0
      child = child->next;
6543
0
  }
6544
0
    }
6545
6546
0
    return (ret);
6547
0
}
6548
6549
/**
6550
 * xmlSchemaParseFacet:
6551
 * @ctxt:  a schema validation context
6552
 * @schema:  the schema being built
6553
 * @node:  a subtree containing XML Schema information
6554
 *
6555
 * parse a XML schema Facet declaration
6556
 * *WARNING* this interface is highly subject to change
6557
 *
6558
 * Returns the new type structure or NULL in case of error
6559
 */
6560
static xmlSchemaFacetPtr
6561
xmlSchemaParseFacet(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
6562
                    xmlNodePtr node)
6563
0
{
6564
0
    xmlSchemaFacetPtr facet;
6565
0
    xmlNodePtr child = NULL;
6566
0
    const xmlChar *value;
6567
6568
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
6569
0
        return (NULL);
6570
6571
0
    facet = xmlSchemaNewFacet();
6572
0
    if (facet == NULL) {
6573
0
        xmlSchemaPErrMemory(ctxt);
6574
0
        return (NULL);
6575
0
    }
6576
0
    facet->node = node;
6577
0
    value = xmlSchemaGetProp(ctxt, node, "value");
6578
0
    if (value == NULL) {
6579
0
        xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_FACET_NO_VALUE,
6580
0
                       "Facet %s has no value\n", node->name, NULL);
6581
0
        xmlSchemaFreeFacet(facet);
6582
0
        return (NULL);
6583
0
    }
6584
0
    if (IS_SCHEMA(node, "minInclusive")) {
6585
0
        facet->type = XML_SCHEMA_FACET_MININCLUSIVE;
6586
0
    } else if (IS_SCHEMA(node, "minExclusive")) {
6587
0
        facet->type = XML_SCHEMA_FACET_MINEXCLUSIVE;
6588
0
    } else if (IS_SCHEMA(node, "maxInclusive")) {
6589
0
        facet->type = XML_SCHEMA_FACET_MAXINCLUSIVE;
6590
0
    } else if (IS_SCHEMA(node, "maxExclusive")) {
6591
0
        facet->type = XML_SCHEMA_FACET_MAXEXCLUSIVE;
6592
0
    } else if (IS_SCHEMA(node, "totalDigits")) {
6593
0
        facet->type = XML_SCHEMA_FACET_TOTALDIGITS;
6594
0
    } else if (IS_SCHEMA(node, "fractionDigits")) {
6595
0
        facet->type = XML_SCHEMA_FACET_FRACTIONDIGITS;
6596
0
    } else if (IS_SCHEMA(node, "pattern")) {
6597
0
        facet->type = XML_SCHEMA_FACET_PATTERN;
6598
0
    } else if (IS_SCHEMA(node, "enumeration")) {
6599
0
        facet->type = XML_SCHEMA_FACET_ENUMERATION;
6600
0
    } else if (IS_SCHEMA(node, "whiteSpace")) {
6601
0
        facet->type = XML_SCHEMA_FACET_WHITESPACE;
6602
0
    } else if (IS_SCHEMA(node, "length")) {
6603
0
        facet->type = XML_SCHEMA_FACET_LENGTH;
6604
0
    } else if (IS_SCHEMA(node, "maxLength")) {
6605
0
        facet->type = XML_SCHEMA_FACET_MAXLENGTH;
6606
0
    } else if (IS_SCHEMA(node, "minLength")) {
6607
0
        facet->type = XML_SCHEMA_FACET_MINLENGTH;
6608
0
    } else {
6609
0
        xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_FACET_TYPE,
6610
0
                       "Unknown facet type %s\n", node->name, NULL);
6611
0
        xmlSchemaFreeFacet(facet);
6612
0
        return (NULL);
6613
0
    }
6614
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
6615
0
    facet->value = value;
6616
0
    if ((facet->type != XML_SCHEMA_FACET_PATTERN) &&
6617
0
  (facet->type != XML_SCHEMA_FACET_ENUMERATION)) {
6618
0
  const xmlChar *fixed;
6619
6620
0
  fixed = xmlSchemaGetProp(ctxt, node, "fixed");
6621
0
  if (fixed != NULL) {
6622
0
      if (xmlStrEqual(fixed, BAD_CAST "true"))
6623
0
    facet->fixed = 1;
6624
0
  }
6625
0
    }
6626
0
    child = node->children;
6627
6628
0
    if (IS_SCHEMA(child, "annotation")) {
6629
0
        facet->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
6630
0
        child = child->next;
6631
0
    }
6632
0
    if (child != NULL) {
6633
0
        xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_FACET_CHILD,
6634
0
                       "Facet %s has unexpected child content\n",
6635
0
                       node->name, NULL);
6636
0
    }
6637
0
    return (facet);
6638
0
}
6639
6640
/**
6641
 * xmlSchemaParseWildcardNs:
6642
 * @ctxt:  a schema parser context
6643
 * @wildc:  the wildcard, already created
6644
 * @node:  a subtree containing XML Schema information
6645
 *
6646
 * Parses the attribute "processContents" and "namespace"
6647
 * of a xsd:anyAttribute and xsd:any.
6648
 * *WARNING* this interface is highly subject to change
6649
 *
6650
 * Returns 0 if everything goes fine, a positive error code
6651
 * if something is not valid and -1 if an internal error occurs.
6652
 */
6653
static int
6654
xmlSchemaParseWildcardNs(xmlSchemaParserCtxtPtr ctxt,
6655
       xmlSchemaPtr schema ATTRIBUTE_UNUSED,
6656
       xmlSchemaWildcardPtr wildc,
6657
       xmlNodePtr node)
6658
0
{
6659
0
    const xmlChar *pc, *ns, *dictnsItem;
6660
0
    int ret = 0;
6661
0
    xmlChar *nsItem;
6662
0
    xmlSchemaWildcardNsPtr tmp, lastNs = NULL;
6663
0
    xmlAttrPtr attr;
6664
6665
0
    pc = xmlSchemaGetProp(ctxt, node, "processContents");
6666
0
    if ((pc == NULL)
6667
0
        || (xmlStrEqual(pc, (const xmlChar *) "strict"))) {
6668
0
        wildc->processContents = XML_SCHEMAS_ANY_STRICT;
6669
0
    } else if (xmlStrEqual(pc, (const xmlChar *) "skip")) {
6670
0
        wildc->processContents = XML_SCHEMAS_ANY_SKIP;
6671
0
    } else if (xmlStrEqual(pc, (const xmlChar *) "lax")) {
6672
0
        wildc->processContents = XML_SCHEMAS_ANY_LAX;
6673
0
    } else {
6674
0
        xmlSchemaPSimpleTypeErr(ctxt,
6675
0
      XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
6676
0
      NULL, node,
6677
0
      NULL, "(strict | skip | lax)", pc,
6678
0
      NULL, NULL, NULL);
6679
0
        wildc->processContents = XML_SCHEMAS_ANY_STRICT;
6680
0
  ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
6681
0
    }
6682
    /*
6683
     * Build the namespace constraints.
6684
     */
6685
0
    attr = xmlSchemaGetPropNode(node, "namespace");
6686
0
    ns = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
6687
0
    if (ns == NULL)
6688
0
        return (-1);
6689
0
    if ((attr == NULL) || (xmlStrEqual(ns, BAD_CAST "##any")))
6690
0
  wildc->any = 1;
6691
0
    else if (xmlStrEqual(ns, BAD_CAST "##other")) {
6692
0
  wildc->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
6693
0
  if (wildc->negNsSet == NULL) {
6694
0
      return (-1);
6695
0
  }
6696
0
  wildc->negNsSet->value = ctxt->targetNamespace;
6697
0
    } else {
6698
0
  const xmlChar *end, *cur;
6699
6700
0
  cur = ns;
6701
0
  do {
6702
0
      while (IS_BLANK_CH(*cur))
6703
0
    cur++;
6704
0
      end = cur;
6705
0
      while ((*end != 0) && (!(IS_BLANK_CH(*end))))
6706
0
    end++;
6707
0
      if (end == cur)
6708
0
    break;
6709
0
      nsItem = xmlStrndup(cur, end - cur);
6710
0
      if ((xmlStrEqual(nsItem, BAD_CAST "##other")) ||
6711
0
        (xmlStrEqual(nsItem, BAD_CAST "##any"))) {
6712
0
    xmlSchemaPSimpleTypeErr(ctxt,
6713
0
        XML_SCHEMAP_WILDCARD_INVALID_NS_MEMBER,
6714
0
        NULL, (xmlNodePtr) attr,
6715
0
        NULL,
6716
0
        "((##any | ##other) | List of (xs:anyURI | "
6717
0
        "(##targetNamespace | ##local)))",
6718
0
        nsItem, NULL, NULL, NULL);
6719
0
    ret = XML_SCHEMAP_WILDCARD_INVALID_NS_MEMBER;
6720
0
      } else {
6721
0
    if (xmlStrEqual(nsItem, BAD_CAST "##targetNamespace")) {
6722
0
        dictnsItem = ctxt->targetNamespace;
6723
0
    } else if (xmlStrEqual(nsItem, BAD_CAST "##local")) {
6724
0
        dictnsItem = NULL;
6725
0
    } else {
6726
        /*
6727
        * Validate the item (anyURI).
6728
        */
6729
0
        xmlSchemaPValAttrNodeValue(ctxt, NULL, attr,
6730
0
      nsItem, xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI));
6731
0
        dictnsItem = xmlDictLookup(ctxt->dict, nsItem, -1);
6732
0
    }
6733
    /*
6734
    * Avoid duplicate namespaces.
6735
    */
6736
0
    tmp = wildc->nsSet;
6737
0
    while (tmp != NULL) {
6738
0
        if (dictnsItem == tmp->value)
6739
0
      break;
6740
0
        tmp = tmp->next;
6741
0
    }
6742
0
    if (tmp == NULL) {
6743
0
        tmp = xmlSchemaNewWildcardNsConstraint(ctxt);
6744
0
        if (tmp == NULL) {
6745
0
      xmlFree(nsItem);
6746
0
      return (-1);
6747
0
        }
6748
0
        tmp->value = dictnsItem;
6749
0
        tmp->next = NULL;
6750
0
        if (wildc->nsSet == NULL)
6751
0
      wildc->nsSet = tmp;
6752
0
        else if (lastNs != NULL)
6753
0
      lastNs->next = tmp;
6754
0
        lastNs = tmp;
6755
0
    }
6756
6757
0
      }
6758
0
      xmlFree(nsItem);
6759
0
      cur = end;
6760
0
  } while (*cur != 0);
6761
0
    }
6762
0
    return (ret);
6763
0
}
6764
6765
static int
6766
xmlSchemaPCheckParticleCorrect_2(xmlSchemaParserCtxtPtr ctxt,
6767
         xmlSchemaParticlePtr item ATTRIBUTE_UNUSED,
6768
         xmlNodePtr node,
6769
         int minOccurs,
6770
0
         int maxOccurs) {
6771
6772
0
    if ((maxOccurs == 0) && ( minOccurs == 0))
6773
0
  return (0);
6774
0
    if (maxOccurs != UNBOUNDED) {
6775
  /*
6776
  * TODO: Maybe we should better not create the particle,
6777
  * if min/max is invalid, since it could confuse the build of the
6778
  * content model.
6779
  */
6780
  /*
6781
  * 3.9.6 Schema Component Constraint: Particle Correct
6782
  *
6783
  */
6784
0
  if (maxOccurs < 1) {
6785
      /*
6786
      * 2.2 {max occurs} must be greater than or equal to 1.
6787
      */
6788
0
      xmlSchemaPCustomAttrErr(ctxt,
6789
0
    XML_SCHEMAP_P_PROPS_CORRECT_2_2,
6790
0
    NULL, NULL,
6791
0
    xmlSchemaGetPropNode(node, "maxOccurs"),
6792
0
    "The value must be greater than or equal to 1");
6793
0
      return (XML_SCHEMAP_P_PROPS_CORRECT_2_2);
6794
0
  } else if (minOccurs > maxOccurs) {
6795
      /*
6796
      * 2.1 {min occurs} must not be greater than {max occurs}.
6797
      */
6798
0
      xmlSchemaPCustomAttrErr(ctxt,
6799
0
    XML_SCHEMAP_P_PROPS_CORRECT_2_1,
6800
0
    NULL, NULL,
6801
0
    xmlSchemaGetPropNode(node, "minOccurs"),
6802
0
    "The value must not be greater than the value of 'maxOccurs'");
6803
0
      return (XML_SCHEMAP_P_PROPS_CORRECT_2_1);
6804
0
  }
6805
0
    }
6806
0
    return (0);
6807
0
}
6808
6809
/**
6810
 * xmlSchemaParseAny:
6811
 * @ctxt:  a schema validation context
6812
 * @schema:  the schema being built
6813
 * @node:  a subtree containing XML Schema information
6814
 *
6815
 * Parsea a XML schema <any> element. A particle and wildcard
6816
 * will be created (except if minOccurs==maxOccurs==0, in this case
6817
 * nothing will be created).
6818
 * *WARNING* this interface is highly subject to change
6819
 *
6820
 * Returns the particle or NULL in case of error or if minOccurs==maxOccurs==0
6821
 */
6822
static xmlSchemaParticlePtr
6823
xmlSchemaParseAny(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
6824
                  xmlNodePtr node)
6825
0
{
6826
0
    xmlSchemaParticlePtr particle;
6827
0
    xmlNodePtr child = NULL;
6828
0
    xmlSchemaWildcardPtr wild;
6829
0
    int min, max;
6830
0
    xmlAttrPtr attr;
6831
0
    xmlSchemaAnnotPtr annot = NULL;
6832
6833
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
6834
0
        return (NULL);
6835
    /*
6836
    * Check for illegal attributes.
6837
    */
6838
0
    attr = node->properties;
6839
0
    while (attr != NULL) {
6840
0
  if (attr->ns == NULL) {
6841
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
6842
0
    (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) &&
6843
0
    (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) &&
6844
0
          (!xmlStrEqual(attr->name, BAD_CAST "namespace")) &&
6845
0
    (!xmlStrEqual(attr->name, BAD_CAST "processContents"))) {
6846
0
    xmlSchemaPIllegalAttrErr(ctxt,
6847
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
6848
0
      }
6849
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
6850
0
      xmlSchemaPIllegalAttrErr(ctxt,
6851
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
6852
0
  }
6853
0
  attr = attr->next;
6854
0
    }
6855
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
6856
    /*
6857
    * minOccurs/maxOccurs.
6858
    */
6859
0
    max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1,
6860
0
  "(xs:nonNegativeInteger | unbounded)");
6861
0
    min = xmlGetMinOccurs(ctxt, node, 0, -1, 1,
6862
0
  "xs:nonNegativeInteger");
6863
0
    xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max);
6864
    /*
6865
    * Create & parse the wildcard.
6866
    */
6867
0
    wild = xmlSchemaAddWildcard(ctxt, schema, XML_SCHEMA_TYPE_ANY, node);
6868
0
    if (wild == NULL)
6869
0
  return (NULL);
6870
0
    xmlSchemaParseWildcardNs(ctxt, schema, wild, node);
6871
    /*
6872
    * And now for the children...
6873
    */
6874
0
    child = node->children;
6875
0
    if (IS_SCHEMA(child, "annotation")) {
6876
0
        annot = xmlSchemaParseAnnotation(ctxt, child, 1);
6877
0
        child = child->next;
6878
0
    }
6879
0
    if (child != NULL) {
6880
0
  xmlSchemaPContentErr(ctxt,
6881
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
6882
0
      NULL, node, child,
6883
0
      NULL, "(annotation?)");
6884
0
    }
6885
    /*
6886
    * No component if minOccurs==maxOccurs==0.
6887
    */
6888
0
    if ((min == 0) && (max == 0)) {
6889
  /* Don't free the wildcard, since it's already on the list. */
6890
0
  return (NULL);
6891
0
    }
6892
    /*
6893
    * Create the particle.
6894
    */
6895
0
    particle = xmlSchemaAddParticle(ctxt, node, min, max);
6896
0
    if (particle == NULL)
6897
0
        return (NULL);
6898
0
    particle->annot = annot;
6899
0
    particle->children = (xmlSchemaTreeItemPtr) wild;
6900
6901
0
    return (particle);
6902
0
}
6903
6904
/**
6905
 * xmlSchemaParseNotation:
6906
 * @ctxt:  a schema validation context
6907
 * @schema:  the schema being built
6908
 * @node:  a subtree containing XML Schema information
6909
 *
6910
 * parse a XML schema Notation declaration
6911
 *
6912
 * Returns the new structure or NULL in case of error
6913
 */
6914
static xmlSchemaNotationPtr
6915
xmlSchemaParseNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
6916
                       xmlNodePtr node)
6917
0
{
6918
0
    const xmlChar *name;
6919
0
    xmlSchemaNotationPtr ret;
6920
0
    xmlNodePtr child = NULL;
6921
6922
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
6923
0
        return (NULL);
6924
0
    name = xmlSchemaGetProp(ctxt, node, "name");
6925
0
    if (name == NULL) {
6926
0
        xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_NOTATION_NO_NAME,
6927
0
                       "Notation has no name\n", NULL, NULL);
6928
0
        return (NULL);
6929
0
    }
6930
0
    ret = xmlSchemaAddNotation(ctxt, schema, name,
6931
0
  ctxt->targetNamespace, node);
6932
0
    if (ret == NULL)
6933
0
        return (NULL);
6934
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
6935
6936
0
    child = node->children;
6937
0
    if (IS_SCHEMA(child, "annotation")) {
6938
0
        ret->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
6939
0
        child = child->next;
6940
0
    }
6941
0
    if (child != NULL) {
6942
0
  xmlSchemaPContentErr(ctxt,
6943
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
6944
0
      NULL, node, child,
6945
0
      NULL, "(annotation?)");
6946
0
    }
6947
6948
0
    return (ret);
6949
0
}
6950
6951
/**
6952
 * xmlSchemaParseAnyAttribute:
6953
 * @ctxt:  a schema validation context
6954
 * @schema:  the schema being built
6955
 * @node:  a subtree containing XML Schema information
6956
 *
6957
 * parse a XML schema AnyAttribute declaration
6958
 * *WARNING* this interface is highly subject to change
6959
 *
6960
 * Returns a wildcard or NULL.
6961
 */
6962
static xmlSchemaWildcardPtr
6963
xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt,
6964
                           xmlSchemaPtr schema, xmlNodePtr node)
6965
0
{
6966
0
    xmlSchemaWildcardPtr ret;
6967
0
    xmlNodePtr child = NULL;
6968
0
    xmlAttrPtr attr;
6969
6970
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
6971
0
        return (NULL);
6972
6973
0
    ret = xmlSchemaAddWildcard(ctxt, schema, XML_SCHEMA_TYPE_ANY_ATTRIBUTE,
6974
0
  node);
6975
0
    if (ret == NULL) {
6976
0
        return (NULL);
6977
0
    }
6978
    /*
6979
    * Check for illegal attributes.
6980
    */
6981
0
    attr = node->properties;
6982
0
    while (attr != NULL) {
6983
0
  if (attr->ns == NULL) {
6984
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
6985
0
          (!xmlStrEqual(attr->name, BAD_CAST "namespace")) &&
6986
0
    (!xmlStrEqual(attr->name, BAD_CAST "processContents"))) {
6987
0
    xmlSchemaPIllegalAttrErr(ctxt,
6988
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
6989
0
      }
6990
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
6991
0
      xmlSchemaPIllegalAttrErr(ctxt,
6992
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
6993
0
  }
6994
0
  attr = attr->next;
6995
0
    }
6996
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
6997
    /*
6998
    * Parse the namespace list.
6999
    */
7000
0
    if (xmlSchemaParseWildcardNs(ctxt, schema, ret, node) != 0)
7001
0
  return (NULL);
7002
    /*
7003
    * And now for the children...
7004
    */
7005
0
    child = node->children;
7006
0
    if (IS_SCHEMA(child, "annotation")) {
7007
0
        ret->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
7008
0
        child = child->next;
7009
0
    }
7010
0
    if (child != NULL) {
7011
0
  xmlSchemaPContentErr(ctxt,
7012
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
7013
0
      NULL, node, child,
7014
0
      NULL, "(annotation?)");
7015
0
    }
7016
7017
0
    return (ret);
7018
0
}
7019
7020
7021
/**
7022
 * xmlSchemaParseAttribute:
7023
 * @ctxt:  a schema validation context
7024
 * @schema:  the schema being built
7025
 * @node:  a subtree containing XML Schema information
7026
 *
7027
 * parse a XML schema Attribute declaration
7028
 * *WARNING* this interface is highly subject to change
7029
 *
7030
 * Returns the attribute declaration.
7031
 */
7032
static xmlSchemaBasicItemPtr
7033
xmlSchemaParseLocalAttribute(xmlSchemaParserCtxtPtr pctxt,
7034
           xmlSchemaPtr schema,
7035
           xmlNodePtr node,
7036
           xmlSchemaItemListPtr uses,
7037
           int parentType)
7038
0
{
7039
0
    const xmlChar *attrValue, *name = NULL, *ns = NULL;
7040
0
    xmlSchemaAttributeUsePtr use = NULL;
7041
0
    xmlNodePtr child = NULL;
7042
0
    xmlAttrPtr attr;
7043
0
    const xmlChar *tmpNs = NULL, *tmpName = NULL, *defValue = NULL;
7044
0
    int isRef = 0, occurs = XML_SCHEMAS_ATTR_USE_OPTIONAL;
7045
0
    int nberrors, hasForm = 0, defValueType = 0;
7046
7047
0
#define WXS_ATTR_DEF_VAL_DEFAULT 1
7048
0
#define WXS_ATTR_DEF_VAL_FIXED 2
7049
7050
    /*
7051
     * 3.2.3 Constraints on XML Representations of Attribute Declarations
7052
     */
7053
7054
0
    if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
7055
0
        return (NULL);
7056
0
    attr = xmlSchemaGetPropNode(node, "ref");
7057
0
    if (attr != NULL) {
7058
0
  if (xmlSchemaPValAttrNodeQName(pctxt, schema,
7059
0
      NULL, attr, &tmpNs, &tmpName) != 0) {
7060
0
      return (NULL);
7061
0
  }
7062
0
  if (xmlSchemaCheckReference(pctxt, schema, node, attr, tmpNs) != 0)
7063
0
      return(NULL);
7064
0
  isRef = 1;
7065
0
    }
7066
0
    nberrors = pctxt->nberrors;
7067
    /*
7068
    * Check for illegal attributes.
7069
    */
7070
0
    attr = node->properties;
7071
0
    while (attr != NULL) {
7072
0
  if (attr->ns == NULL) {
7073
0
      if (isRef) {
7074
0
    if (xmlStrEqual(attr->name, BAD_CAST "id")) {
7075
0
        xmlSchemaPValAttrNodeID(pctxt, attr);
7076
0
        goto attr_next;
7077
0
    } else if (xmlStrEqual(attr->name, BAD_CAST "ref")) {
7078
0
        goto attr_next;
7079
0
    }
7080
0
      } else {
7081
0
    if (xmlStrEqual(attr->name, BAD_CAST "name")) {
7082
0
        goto attr_next;
7083
0
    } else if (xmlStrEqual(attr->name, BAD_CAST "id")) {
7084
0
        xmlSchemaPValAttrNodeID(pctxt, attr);
7085
0
        goto attr_next;
7086
0
    } else if (xmlStrEqual(attr->name, BAD_CAST "type")) {
7087
0
        xmlSchemaPValAttrNodeQName(pctxt, schema, NULL,
7088
0
      attr, &tmpNs, &tmpName);
7089
0
        goto attr_next;
7090
0
    } else if (xmlStrEqual(attr->name, BAD_CAST "form")) {
7091
        /*
7092
        * Evaluate the target namespace
7093
        */
7094
0
        hasForm = 1;
7095
0
        attrValue = xmlSchemaGetNodeContent(pctxt,
7096
0
      (xmlNodePtr) attr);
7097
0
        if (xmlStrEqual(attrValue, BAD_CAST "qualified")) {
7098
0
      ns = pctxt->targetNamespace;
7099
0
        } else if (!xmlStrEqual(attrValue, BAD_CAST "unqualified"))
7100
0
        {
7101
0
      xmlSchemaPSimpleTypeErr(pctxt,
7102
0
          XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
7103
0
          NULL, (xmlNodePtr) attr,
7104
0
          NULL, "(qualified | unqualified)",
7105
0
          attrValue, NULL, NULL, NULL);
7106
0
        }
7107
0
        goto attr_next;
7108
0
    }
7109
0
      }
7110
0
      if (xmlStrEqual(attr->name, BAD_CAST "use")) {
7111
7112
0
    attrValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
7113
    /* TODO: Maybe we need to normalize the value beforehand. */
7114
0
    if (xmlStrEqual(attrValue, BAD_CAST "optional"))
7115
0
        occurs = XML_SCHEMAS_ATTR_USE_OPTIONAL;
7116
0
    else if (xmlStrEqual(attrValue, BAD_CAST "prohibited"))
7117
0
        occurs = XML_SCHEMAS_ATTR_USE_PROHIBITED;
7118
0
    else if (xmlStrEqual(attrValue, BAD_CAST "required"))
7119
0
        occurs = XML_SCHEMAS_ATTR_USE_REQUIRED;
7120
0
    else {
7121
0
        xmlSchemaPSimpleTypeErr(pctxt,
7122
0
      XML_SCHEMAP_INVALID_ATTR_USE,
7123
0
      NULL, (xmlNodePtr) attr,
7124
0
      NULL, "(optional | prohibited | required)",
7125
0
      attrValue, NULL, NULL, NULL);
7126
0
    }
7127
0
    goto attr_next;
7128
0
      } else if (xmlStrEqual(attr->name, BAD_CAST "default")) {
7129
    /*
7130
    * 3.2.3 : 1
7131
    * default and fixed must not both be present.
7132
    */
7133
0
    if (defValue) {
7134
0
        xmlSchemaPMutualExclAttrErr(pctxt,
7135
0
      XML_SCHEMAP_SRC_ATTRIBUTE_1,
7136
0
      NULL, attr, "default", "fixed");
7137
0
    } else {
7138
0
        defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
7139
0
        defValueType = WXS_ATTR_DEF_VAL_DEFAULT;
7140
0
    }
7141
0
    goto attr_next;
7142
0
      } else if (xmlStrEqual(attr->name, BAD_CAST "fixed")) {
7143
    /*
7144
    * 3.2.3 : 1
7145
    * default and fixed must not both be present.
7146
    */
7147
0
    if (defValue) {
7148
0
        xmlSchemaPMutualExclAttrErr(pctxt,
7149
0
      XML_SCHEMAP_SRC_ATTRIBUTE_1,
7150
0
      NULL, attr, "default", "fixed");
7151
0
    } else {
7152
0
        defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
7153
0
        defValueType = WXS_ATTR_DEF_VAL_FIXED;
7154
0
    }
7155
0
    goto attr_next;
7156
0
      }
7157
0
  } else if (! xmlStrEqual(attr->ns->href, xmlSchemaNs))
7158
0
      goto attr_next;
7159
7160
0
  xmlSchemaPIllegalAttrErr(pctxt,
7161
0
      XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
7162
7163
0
attr_next:
7164
0
  attr = attr->next;
7165
0
    }
7166
    /*
7167
    * 3.2.3 : 2
7168
    * If default and use are both present, use must have
7169
    * the actual value optional.
7170
    */
7171
0
    if ((defValueType == WXS_ATTR_DEF_VAL_DEFAULT) &&
7172
0
  (occurs != XML_SCHEMAS_ATTR_USE_OPTIONAL)) {
7173
0
  xmlSchemaPSimpleTypeErr(pctxt,
7174
0
      XML_SCHEMAP_SRC_ATTRIBUTE_2,
7175
0
      NULL, node, NULL,
7176
0
      "(optional | prohibited | required)", NULL,
7177
0
      "The value of the attribute 'use' must be 'optional' "
7178
0
      "if the attribute 'default' is present",
7179
0
      NULL, NULL);
7180
0
    }
7181
    /*
7182
    * We want correct attributes.
7183
    */
7184
0
    if (nberrors != pctxt->nberrors)
7185
0
  return(NULL);
7186
0
    if (! isRef) {
7187
0
  xmlSchemaAttributePtr attrDecl;
7188
7189
  /* TODO: move XML_SCHEMAS_QUALIF_ATTR to the parser. */
7190
0
  if ((! hasForm) && (schema->flags & XML_SCHEMAS_QUALIF_ATTR))
7191
0
      ns = pctxt->targetNamespace;
7192
  /*
7193
  * 3.2.6 Schema Component Constraint: xsi: Not Allowed
7194
  * TODO: Move this to the component layer.
7195
  */
7196
0
  if (xmlStrEqual(ns, xmlSchemaInstanceNs)) {
7197
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
7198
0
    XML_SCHEMAP_NO_XSI,
7199
0
    node, NULL,
7200
0
    "The target namespace must not match '%s'",
7201
0
    xmlSchemaInstanceNs, NULL);
7202
0
  }
7203
0
  attr = xmlSchemaGetPropNode(node, "name");
7204
0
  if (attr == NULL) {
7205
0
      xmlSchemaPMissingAttrErr(pctxt, XML_SCHEMAP_S4S_ATTR_MISSING,
7206
0
    NULL, node, "name", NULL);
7207
0
      return (NULL);
7208
0
  }
7209
0
  if (xmlSchemaPValAttrNode(pctxt, NULL, attr,
7210
0
      xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
7211
0
      return (NULL);
7212
0
  }
7213
  /*
7214
  * 3.2.6 Schema Component Constraint: xmlns Not Allowed
7215
  * TODO: Move this to the component layer.
7216
  */
7217
0
  if (xmlStrEqual(name, BAD_CAST "xmlns")) {
7218
0
      xmlSchemaPSimpleTypeErr(pctxt,
7219
0
    XML_SCHEMAP_NO_XMLNS,
7220
0
    NULL, (xmlNodePtr) attr,
7221
0
    xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), NULL, NULL,
7222
0
    "The value of the attribute must not match 'xmlns'",
7223
0
    NULL, NULL);
7224
0
      return (NULL);
7225
0
  }
7226
0
  if (occurs == XML_SCHEMAS_ATTR_USE_PROHIBITED)
7227
0
      goto check_children;
7228
  /*
7229
  * Create the attribute use component.
7230
  */
7231
0
  use = xmlSchemaAddAttributeUse(pctxt, node);
7232
0
  if (use == NULL)
7233
0
      return(NULL);
7234
0
  use->occurs = occurs;
7235
  /*
7236
  * Create the attribute declaration.
7237
  */
7238
0
  attrDecl = xmlSchemaAddAttribute(pctxt, schema, name, ns, node, 0);
7239
0
  if (attrDecl == NULL)
7240
0
      return (NULL);
7241
0
  if (tmpName != NULL) {
7242
0
      attrDecl->typeName = tmpName;
7243
0
      attrDecl->typeNs = tmpNs;
7244
0
  }
7245
0
  use->attrDecl = attrDecl;
7246
  /*
7247
  * Value constraint.
7248
  */
7249
0
  if (defValue != NULL) {
7250
0
      attrDecl->defValue = defValue;
7251
0
      if (defValueType == WXS_ATTR_DEF_VAL_FIXED)
7252
0
    attrDecl->flags |= XML_SCHEMAS_ATTR_FIXED;
7253
0
  }
7254
0
    } else if (occurs != XML_SCHEMAS_ATTR_USE_PROHIBITED) {
7255
0
  xmlSchemaQNameRefPtr ref;
7256
7257
  /*
7258
  * Create the attribute use component.
7259
  */
7260
0
  use = xmlSchemaAddAttributeUse(pctxt, node);
7261
0
  if (use == NULL)
7262
0
      return(NULL);
7263
  /*
7264
  * We need to resolve the reference at later stage.
7265
  */
7266
0
  WXS_ADD_PENDING(pctxt, use);
7267
0
  use->occurs = occurs;
7268
  /*
7269
  * Create a QName reference to the attribute declaration.
7270
  */
7271
0
  ref = xmlSchemaNewQNameRef(pctxt, XML_SCHEMA_TYPE_ATTRIBUTE,
7272
0
      tmpName, tmpNs);
7273
0
  if (ref == NULL)
7274
0
      return(NULL);
7275
  /*
7276
  * Assign the reference. This will be substituted for the
7277
  * referenced attribute declaration when the QName is resolved.
7278
  */
7279
0
  use->attrDecl = WXS_ATTR_CAST ref;
7280
  /*
7281
  * Value constraint.
7282
  */
7283
0
  if (defValue != NULL)
7284
0
      use->defValue = defValue;
7285
0
  if (defValueType == WXS_ATTR_DEF_VAL_FIXED)
7286
0
      use->flags |= XML_SCHEMA_ATTR_USE_FIXED;
7287
0
    }
7288
7289
0
check_children:
7290
    /*
7291
    * And now for the children...
7292
    */
7293
0
    child = node->children;
7294
0
    if (occurs == XML_SCHEMAS_ATTR_USE_PROHIBITED) {
7295
0
  xmlSchemaAttributeUseProhibPtr prohib;
7296
7297
0
  if (IS_SCHEMA(child, "annotation")) {
7298
0
      xmlSchemaParseAnnotation(pctxt, child, 0);
7299
0
      child = child->next;
7300
0
  }
7301
0
  if (child != NULL) {
7302
0
      xmlSchemaPContentErr(pctxt,
7303
0
    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
7304
0
    NULL, node, child, NULL,
7305
0
    "(annotation?)");
7306
0
  }
7307
  /*
7308
  * Check for pointlessness of attribute prohibitions.
7309
  */
7310
0
  if (parentType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP) {
7311
0
      xmlSchemaCustomWarning(ACTXT_CAST pctxt,
7312
0
    XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
7313
0
    node, NULL,
7314
0
    "Skipping attribute use prohibition, since it is "
7315
0
    "pointless inside an <attributeGroup>",
7316
0
    NULL, NULL, NULL);
7317
0
      return(NULL);
7318
0
  } else if (parentType == XML_SCHEMA_TYPE_EXTENSION) {
7319
0
      xmlSchemaCustomWarning(ACTXT_CAST pctxt,
7320
0
    XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
7321
0
    node, NULL,
7322
0
    "Skipping attribute use prohibition, since it is "
7323
0
    "pointless when extending a type",
7324
0
    NULL, NULL, NULL);
7325
0
      return(NULL);
7326
0
  }
7327
0
  if (! isRef) {
7328
0
      tmpName = name;
7329
0
      tmpNs = ns;
7330
0
  }
7331
  /*
7332
  * Check for duplicate attribute prohibitions.
7333
  */
7334
0
  if (uses) {
7335
0
      int i;
7336
7337
0
      for (i = 0; i < uses->nbItems; i++) {
7338
0
    use = uses->items[i];
7339
0
    if ((use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) &&
7340
0
        (tmpName == (WXS_ATTR_PROHIB_CAST use)->name) &&
7341
0
        (tmpNs == (WXS_ATTR_PROHIB_CAST use)->targetNamespace))
7342
0
    {
7343
0
        xmlChar *str = NULL;
7344
7345
0
        xmlSchemaCustomWarning(ACTXT_CAST pctxt,
7346
0
      XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
7347
0
      node, NULL,
7348
0
      "Skipping duplicate attribute use prohibition '%s'",
7349
0
      xmlSchemaFormatQName(&str, tmpNs, tmpName),
7350
0
      NULL, NULL);
7351
0
        FREE_AND_NULL(str)
7352
0
        return(NULL);
7353
0
    }
7354
0
      }
7355
0
  }
7356
  /*
7357
  * Create the attribute prohibition helper component.
7358
  */
7359
0
  prohib = xmlSchemaAddAttributeUseProhib(pctxt);
7360
0
  if (prohib == NULL)
7361
0
      return(NULL);
7362
0
  prohib->node = node;
7363
0
  prohib->name = tmpName;
7364
0
  prohib->targetNamespace = tmpNs;
7365
0
  if (isRef) {
7366
      /*
7367
      * We need at least to resolve to the attribute declaration.
7368
      */
7369
0
      WXS_ADD_PENDING(pctxt, prohib);
7370
0
  }
7371
0
  return(WXS_BASIC_CAST prohib);
7372
0
    } else {
7373
0
  if (IS_SCHEMA(child, "annotation")) {
7374
      /*
7375
      * TODO: Should this go into the attr decl?
7376
      */
7377
0
      use->annot = xmlSchemaParseAnnotation(pctxt, child, 1);
7378
0
      child = child->next;
7379
0
  }
7380
0
  if (isRef) {
7381
0
      if (child != NULL) {
7382
0
    if (IS_SCHEMA(child, "simpleType"))
7383
        /*
7384
        * 3.2.3 : 3.2
7385
        * If ref is present, then all of <simpleType>,
7386
        * form and type must be absent.
7387
        */
7388
0
        xmlSchemaPContentErr(pctxt,
7389
0
      XML_SCHEMAP_SRC_ATTRIBUTE_3_2,
7390
0
      NULL, node, child, NULL,
7391
0
      "(annotation?)");
7392
0
    else
7393
0
        xmlSchemaPContentErr(pctxt,
7394
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
7395
0
      NULL, node, child, NULL,
7396
0
      "(annotation?)");
7397
0
      }
7398
0
  } else {
7399
0
      if (IS_SCHEMA(child, "simpleType")) {
7400
0
    if (WXS_ATTRUSE_DECL(use)->typeName != NULL) {
7401
        /*
7402
        * 3.2.3 : 4
7403
        * type and <simpleType> must not both be present.
7404
        */
7405
0
        xmlSchemaPContentErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_4,
7406
0
      NULL, node, child,
7407
0
      "The attribute 'type' and the <simpleType> child "
7408
0
      "are mutually exclusive", NULL);
7409
0
    } else
7410
0
        WXS_ATTRUSE_TYPEDEF(use) =
7411
0
      xmlSchemaParseSimpleType(pctxt, schema, child, 0);
7412
0
    child = child->next;
7413
0
      }
7414
0
      if (child != NULL)
7415
0
    xmlSchemaPContentErr(pctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
7416
0
    NULL, node, child, NULL,
7417
0
    "(annotation?, simpleType?)");
7418
0
  }
7419
0
    }
7420
0
    return (WXS_BASIC_CAST use);
7421
0
}
7422
7423
7424
static xmlSchemaAttributePtr
7425
xmlSchemaParseGlobalAttribute(xmlSchemaParserCtxtPtr pctxt,
7426
            xmlSchemaPtr schema,
7427
            xmlNodePtr node)
7428
0
{
7429
0
    const xmlChar *attrValue;
7430
0
    xmlSchemaAttributePtr ret;
7431
0
    xmlNodePtr child = NULL;
7432
0
    xmlAttrPtr attr;
7433
7434
    /*
7435
     * Note that the w3c spec assumes the schema to be validated with schema
7436
     * for schemas beforehand.
7437
     *
7438
     * 3.2.3 Constraints on XML Representations of Attribute Declarations
7439
     */
7440
0
    if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
7441
0
        return (NULL);
7442
    /*
7443
    * 3.2.3 : 3.1
7444
    * One of ref or name must be present, but not both
7445
    */
7446
0
    attr = xmlSchemaGetPropNode(node, "name");
7447
0
    if (attr == NULL) {
7448
0
  xmlSchemaPMissingAttrErr(pctxt, XML_SCHEMAP_S4S_ATTR_MISSING,
7449
0
      NULL, node, "name", NULL);
7450
0
  return (NULL);
7451
0
    }
7452
0
    if (xmlSchemaPValAttrNode(pctxt, NULL, attr,
7453
0
  xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &attrValue) != 0) {
7454
0
  return (NULL);
7455
0
    }
7456
    /*
7457
    * 3.2.6 Schema Component Constraint: xmlns Not Allowed
7458
    * TODO: Move this to the component layer.
7459
    */
7460
0
    if (xmlStrEqual(attrValue, BAD_CAST "xmlns")) {
7461
0
  xmlSchemaPSimpleTypeErr(pctxt,
7462
0
      XML_SCHEMAP_NO_XMLNS,
7463
0
      NULL, (xmlNodePtr) attr,
7464
0
      xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), NULL, NULL,
7465
0
      "The value of the attribute must not match 'xmlns'",
7466
0
      NULL, NULL);
7467
0
  return (NULL);
7468
0
    }
7469
    /*
7470
    * 3.2.6 Schema Component Constraint: xsi: Not Allowed
7471
    * TODO: Move this to the component layer.
7472
    *       Or better leave it here and add it to the component layer
7473
    *       if we have a schema construction API.
7474
    */
7475
0
    if (xmlStrEqual(pctxt->targetNamespace, xmlSchemaInstanceNs)) {
7476
0
  xmlSchemaCustomErr(ACTXT_CAST pctxt,
7477
0
      XML_SCHEMAP_NO_XSI, node, NULL,
7478
0
      "The target namespace must not match '%s'",
7479
0
      xmlSchemaInstanceNs, NULL);
7480
0
    }
7481
7482
0
    ret = xmlSchemaAddAttribute(pctxt, schema, attrValue,
7483
0
  pctxt->targetNamespace, node, 1);
7484
0
    if (ret == NULL)
7485
0
  return (NULL);
7486
0
    ret->flags |= XML_SCHEMAS_ATTR_GLOBAL;
7487
7488
    /*
7489
    * Check for illegal attributes.
7490
    */
7491
0
    attr = node->properties;
7492
0
    while (attr != NULL) {
7493
0
  if (attr->ns == NULL) {
7494
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
7495
0
    (!xmlStrEqual(attr->name, BAD_CAST "default")) &&
7496
0
    (!xmlStrEqual(attr->name, BAD_CAST "fixed")) &&
7497
0
    (!xmlStrEqual(attr->name, BAD_CAST "name")) &&
7498
0
    (!xmlStrEqual(attr->name, BAD_CAST "type")))
7499
0
      {
7500
0
    xmlSchemaPIllegalAttrErr(pctxt,
7501
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
7502
0
      }
7503
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
7504
0
      xmlSchemaPIllegalAttrErr(pctxt,
7505
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
7506
0
  }
7507
0
  attr = attr->next;
7508
0
    }
7509
0
    xmlSchemaPValAttrQName(pctxt, schema, NULL,
7510
0
  node, "type", &ret->typeNs, &ret->typeName);
7511
7512
0
    xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
7513
    /*
7514
    * Attribute "fixed".
7515
    */
7516
0
    ret->defValue = xmlSchemaGetProp(pctxt, node, "fixed");
7517
0
    if (ret->defValue != NULL)
7518
0
  ret->flags |= XML_SCHEMAS_ATTR_FIXED;
7519
    /*
7520
    * Attribute "default".
7521
    */
7522
0
    attr = xmlSchemaGetPropNode(node, "default");
7523
0
    if (attr != NULL) {
7524
  /*
7525
  * 3.2.3 : 1
7526
  * default and fixed must not both be present.
7527
  */
7528
0
  if (ret->flags & XML_SCHEMAS_ATTR_FIXED) {
7529
0
      xmlSchemaPMutualExclAttrErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_1,
7530
0
    WXS_BASIC_CAST ret, attr, "default", "fixed");
7531
0
  } else
7532
0
      ret->defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
7533
0
    }
7534
    /*
7535
    * And now for the children...
7536
    */
7537
0
    child = node->children;
7538
0
    if (IS_SCHEMA(child, "annotation")) {
7539
0
        ret->annot = xmlSchemaParseAnnotation(pctxt, child, 1);
7540
0
        child = child->next;
7541
0
    }
7542
0
    if (IS_SCHEMA(child, "simpleType")) {
7543
0
  if (ret->typeName != NULL) {
7544
      /*
7545
      * 3.2.3 : 4
7546
      * type and <simpleType> must not both be present.
7547
      */
7548
0
      xmlSchemaPContentErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_4,
7549
0
    NULL, node, child,
7550
0
    "The attribute 'type' and the <simpleType> child "
7551
0
    "are mutually exclusive", NULL);
7552
0
  } else
7553
0
      ret->subtypes = xmlSchemaParseSimpleType(pctxt, schema, child, 0);
7554
0
  child = child->next;
7555
0
    }
7556
0
    if (child != NULL)
7557
0
  xmlSchemaPContentErr(pctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
7558
0
      NULL, node, child, NULL,
7559
0
      "(annotation?, simpleType?)");
7560
7561
0
    return (ret);
7562
0
}
7563
7564
/**
7565
 * xmlSchemaParseAttributeGroupRef:
7566
 * @ctxt:  a schema validation context
7567
 * @schema:  the schema being built
7568
 * @node:  a subtree containing XML Schema information
7569
 *
7570
 * Parse an attribute group definition reference.
7571
 * Note that a reference to an attribute group does not
7572
 * correspond to any component at all.
7573
 * *WARNING* this interface is highly subject to change
7574
 *
7575
 * Returns the attribute group or NULL in case of error.
7576
 */
7577
static xmlSchemaQNameRefPtr
7578
xmlSchemaParseAttributeGroupRef(xmlSchemaParserCtxtPtr pctxt,
7579
        xmlSchemaPtr schema,
7580
        xmlNodePtr node)
7581
0
{
7582
0
    xmlSchemaQNameRefPtr ret;
7583
0
    xmlNodePtr child = NULL;
7584
0
    xmlAttrPtr attr;
7585
0
    const xmlChar *refNs = NULL, *ref = NULL;
7586
7587
0
    if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
7588
0
        return (NULL);
7589
7590
0
    attr = xmlSchemaGetPropNode(node, "ref");
7591
0
    if (attr == NULL) {
7592
0
  xmlSchemaPMissingAttrErr(pctxt,
7593
0
      XML_SCHEMAP_S4S_ATTR_MISSING,
7594
0
      NULL, node, "ref", NULL);
7595
0
  return (NULL);
7596
0
    }
7597
0
    xmlSchemaPValAttrNodeQName(pctxt, schema,
7598
0
  NULL, attr, &refNs, &ref);
7599
0
    if (xmlSchemaCheckReference(pctxt, schema, node, attr, refNs) != 0)
7600
0
  return(NULL);
7601
7602
    /*
7603
    * Check for illegal attributes.
7604
    */
7605
0
    attr = node->properties;
7606
0
    while (attr != NULL) {
7607
0
  if (attr->ns == NULL) {
7608
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "ref")) &&
7609
0
    (!xmlStrEqual(attr->name, BAD_CAST "id")))
7610
0
      {
7611
0
    xmlSchemaPIllegalAttrErr(pctxt,
7612
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
7613
0
      }
7614
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
7615
0
      xmlSchemaPIllegalAttrErr(pctxt,
7616
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
7617
0
  }
7618
0
  attr = attr->next;
7619
0
    }
7620
    /* Attribute ID */
7621
0
    xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
7622
7623
    /*
7624
    * And now for the children...
7625
    */
7626
0
    child = node->children;
7627
0
    if (IS_SCHEMA(child, "annotation")) {
7628
  /*
7629
  * TODO: We do not have a place to store the annotation, do we?
7630
  */
7631
0
        xmlSchemaParseAnnotation(pctxt, child, 0);
7632
0
        child = child->next;
7633
0
    }
7634
0
    if (child != NULL) {
7635
0
  xmlSchemaPContentErr(pctxt,
7636
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
7637
0
      NULL, node, child, NULL,
7638
0
      "(annotation?)");
7639
0
    }
7640
7641
    /*
7642
    * Handle attribute group redefinitions.
7643
    */
7644
0
    if (pctxt->isRedefine && pctxt->redef &&
7645
0
  (pctxt->redef->item->type ==
7646
0
      XML_SCHEMA_TYPE_ATTRIBUTEGROUP) &&
7647
0
  (ref == pctxt->redef->refName) &&
7648
0
  (refNs == pctxt->redef->refTargetNs))
7649
0
    {
7650
  /*
7651
  * SPEC src-redefine:
7652
  * (7.1) "If it has an <attributeGroup> among its contents
7653
  * the `actual value` of whose ref [attribute] is the same
7654
  * as the `actual value` of its own name attribute plus
7655
  * target namespace, then it must have exactly one such group."
7656
  */
7657
0
  if (pctxt->redefCounter != 0) {
7658
0
      xmlChar *str = NULL;
7659
7660
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
7661
0
    XML_SCHEMAP_SRC_REDEFINE, node, NULL,
7662
0
    "The redefining attribute group definition "
7663
0
    "'%s' must not contain more than one "
7664
0
    "reference to the redefined definition",
7665
0
    xmlSchemaFormatQName(&str, refNs, ref), NULL);
7666
0
      FREE_AND_NULL(str);
7667
0
      return(NULL);
7668
0
  }
7669
0
  pctxt->redefCounter++;
7670
  /*
7671
  * URGENT TODO: How to ensure that the reference will not be
7672
  * handled by the normal component resolution mechanism?
7673
  */
7674
0
  ret = xmlSchemaNewQNameRef(pctxt,
7675
0
      XML_SCHEMA_TYPE_ATTRIBUTEGROUP, ref, refNs);
7676
0
  if (ret == NULL)
7677
0
      return(NULL);
7678
0
  ret->node = node;
7679
0
  pctxt->redef->reference = WXS_BASIC_CAST ret;
7680
0
    } else {
7681
  /*
7682
  * Create a QName-reference helper component. We will substitute this
7683
  * component for the attribute uses of the referenced attribute group
7684
  * definition.
7685
  */
7686
0
  ret = xmlSchemaNewQNameRef(pctxt,
7687
0
      XML_SCHEMA_TYPE_ATTRIBUTEGROUP, ref, refNs);
7688
0
  if (ret == NULL)
7689
0
      return(NULL);
7690
0
  ret->node = node;
7691
  /* Add to pending items, to be able to resolve the reference. */
7692
0
  WXS_ADD_PENDING(pctxt, ret);
7693
0
    }
7694
0
    return (ret);
7695
0
}
7696
7697
/**
7698
 * xmlSchemaParseAttributeGroupDefinition:
7699
 * @pctxt:  a schema validation context
7700
 * @schema:  the schema being built
7701
 * @node:  a subtree containing XML Schema information
7702
 *
7703
 * parse a XML schema Attribute Group declaration
7704
 * *WARNING* this interface is highly subject to change
7705
 *
7706
 * Returns the attribute group definition or NULL in case of error.
7707
 */
7708
static xmlSchemaAttributeGroupPtr
7709
xmlSchemaParseAttributeGroupDefinition(xmlSchemaParserCtxtPtr pctxt,
7710
               xmlSchemaPtr schema,
7711
               xmlNodePtr node)
7712
0
{
7713
0
    const xmlChar *name;
7714
0
    xmlSchemaAttributeGroupPtr ret;
7715
0
    xmlNodePtr child = NULL;
7716
0
    xmlAttrPtr attr;
7717
0
    int hasRefs = 0;
7718
0
    int res;
7719
7720
0
    if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
7721
0
        return (NULL);
7722
7723
0
    attr = xmlSchemaGetPropNode(node, "name");
7724
0
    if (attr == NULL) {
7725
0
  xmlSchemaPMissingAttrErr(pctxt,
7726
0
      XML_SCHEMAP_S4S_ATTR_MISSING,
7727
0
      NULL, node, "name", NULL);
7728
0
  return (NULL);
7729
0
    }
7730
    /*
7731
    * The name is crucial, exit if invalid.
7732
    */
7733
0
    if (xmlSchemaPValAttrNode(pctxt,
7734
0
  NULL, attr,
7735
0
  xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
7736
0
  return (NULL);
7737
0
    }
7738
0
    ret = xmlSchemaAddAttributeGroupDefinition(pctxt, schema,
7739
0
  name, pctxt->targetNamespace, node);
7740
0
    if (ret == NULL)
7741
0
  return (NULL);
7742
    /*
7743
    * Check for illegal attributes.
7744
    */
7745
0
    attr = node->properties;
7746
0
    while (attr != NULL) {
7747
0
  if (attr->ns == NULL) {
7748
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "name")) &&
7749
0
    (!xmlStrEqual(attr->name, BAD_CAST "id")))
7750
0
      {
7751
0
    xmlSchemaPIllegalAttrErr(pctxt,
7752
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
7753
0
      }
7754
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
7755
0
      xmlSchemaPIllegalAttrErr(pctxt,
7756
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
7757
0
  }
7758
0
  attr = attr->next;
7759
0
    }
7760
    /* Attribute ID */
7761
0
    xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
7762
    /*
7763
    * And now for the children...
7764
    */
7765
0
    child = node->children;
7766
0
    if (IS_SCHEMA(child, "annotation")) {
7767
0
        ret->annot = xmlSchemaParseAnnotation(pctxt, child, 1);
7768
0
        child = child->next;
7769
0
    }
7770
    /*
7771
    * Parse contained attribute decls/refs.
7772
    */
7773
0
    res = xmlSchemaParseLocalAttributes(pctxt, schema, &child,
7774
0
  (xmlSchemaItemListPtr *) &(ret->attrUses),
7775
0
  XML_SCHEMA_TYPE_ATTRIBUTEGROUP, &hasRefs);
7776
0
    if (hasRefs)
7777
0
  ret->flags |= XML_SCHEMAS_ATTRGROUP_HAS_REFS;
7778
0
    if (res == -1)
7779
0
  return(NULL);
7780
    /*
7781
    * Parse the attribute wildcard.
7782
    */
7783
0
    if (IS_SCHEMA(child, "anyAttribute")) {
7784
0
  ret->attributeWildcard = xmlSchemaParseAnyAttribute(pctxt,
7785
0
      schema, child);
7786
0
  child = child->next;
7787
0
    }
7788
0
    if (child != NULL) {
7789
0
  xmlSchemaPContentErr(pctxt,
7790
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
7791
0
      NULL, node, child, NULL,
7792
0
      "(annotation?, ((attribute | attributeGroup)*, anyAttribute?))");
7793
0
    }
7794
0
    return (ret);
7795
0
}
7796
7797
/**
7798
 * xmlSchemaPValAttrFormDefault:
7799
 * @value:  the value
7800
 * @flags: the flags to be modified
7801
 * @flagQualified: the specific flag for "qualified"
7802
 *
7803
 * Returns 0 if the value is valid, 1 otherwise.
7804
 */
7805
static int
7806
xmlSchemaPValAttrFormDefault(const xmlChar *value,
7807
           int *flags,
7808
           int flagQualified)
7809
0
{
7810
0
    if (xmlStrEqual(value, BAD_CAST "qualified")) {
7811
0
  if  ((*flags & flagQualified) == 0)
7812
0
      *flags |= flagQualified;
7813
0
    } else if (!xmlStrEqual(value, BAD_CAST "unqualified"))
7814
0
  return (1);
7815
7816
0
    return (0);
7817
0
}
7818
7819
/**
7820
 * xmlSchemaPValAttrBlockFinal:
7821
 * @value:  the value
7822
 * @flags: the flags to be modified
7823
 * @flagAll: the specific flag for "#all"
7824
 * @flagExtension: the specific flag for "extension"
7825
 * @flagRestriction: the specific flag for "restriction"
7826
 * @flagSubstitution: the specific flag for "substitution"
7827
 * @flagList: the specific flag for "list"
7828
 * @flagUnion: the specific flag for "union"
7829
 *
7830
 * Validates the value of the attribute "final" and "block". The value
7831
 * is converted into the specified flag values and returned in @flags.
7832
 *
7833
 * Returns 0 if the value is valid, 1 otherwise.
7834
 */
7835
7836
static int
7837
xmlSchemaPValAttrBlockFinal(const xmlChar *value,
7838
          int *flags,
7839
          int flagAll,
7840
          int flagExtension,
7841
          int flagRestriction,
7842
          int flagSubstitution,
7843
          int flagList,
7844
          int flagUnion)
7845
0
{
7846
0
    int ret = 0;
7847
7848
    /*
7849
    * TODO: This does not check for duplicate entries.
7850
    */
7851
0
    if ((flags == NULL) || (value == NULL))
7852
0
  return (-1);
7853
0
    if (value[0] == 0)
7854
0
  return (0);
7855
0
    if (xmlStrEqual(value, BAD_CAST "#all")) {
7856
0
  if (flagAll != -1)
7857
0
      *flags |= flagAll;
7858
0
  else {
7859
0
      if (flagExtension != -1)
7860
0
    *flags |= flagExtension;
7861
0
      if (flagRestriction != -1)
7862
0
    *flags |= flagRestriction;
7863
0
      if (flagSubstitution != -1)
7864
0
    *flags |= flagSubstitution;
7865
0
      if (flagList != -1)
7866
0
    *flags |= flagList;
7867
0
      if (flagUnion != -1)
7868
0
    *flags |= flagUnion;
7869
0
  }
7870
0
    } else {
7871
0
  const xmlChar *end, *cur = value;
7872
0
  xmlChar *item;
7873
7874
0
  do {
7875
0
      while (IS_BLANK_CH(*cur))
7876
0
    cur++;
7877
0
      end = cur;
7878
0
      while ((*end != 0) && (!(IS_BLANK_CH(*end))))
7879
0
    end++;
7880
0
      if (end == cur)
7881
0
    break;
7882
0
      item = xmlStrndup(cur, end - cur);
7883
0
      if (xmlStrEqual(item, BAD_CAST "extension")) {
7884
0
    if (flagExtension != -1) {
7885
0
        if ((*flags & flagExtension) == 0)
7886
0
      *flags |= flagExtension;
7887
0
    } else
7888
0
        ret = 1;
7889
0
      } else if (xmlStrEqual(item, BAD_CAST "restriction")) {
7890
0
    if (flagRestriction != -1) {
7891
0
        if ((*flags & flagRestriction) == 0)
7892
0
      *flags |= flagRestriction;
7893
0
    } else
7894
0
        ret = 1;
7895
0
      } else if (xmlStrEqual(item, BAD_CAST "substitution")) {
7896
0
    if (flagSubstitution != -1) {
7897
0
        if ((*flags & flagSubstitution) == 0)
7898
0
      *flags |= flagSubstitution;
7899
0
    } else
7900
0
        ret = 1;
7901
0
      } else if (xmlStrEqual(item, BAD_CAST "list")) {
7902
0
    if (flagList != -1) {
7903
0
        if ((*flags & flagList) == 0)
7904
0
      *flags |= flagList;
7905
0
    } else
7906
0
        ret = 1;
7907
0
      } else if (xmlStrEqual(item, BAD_CAST "union")) {
7908
0
    if (flagUnion != -1) {
7909
0
        if ((*flags & flagUnion) == 0)
7910
0
      *flags |= flagUnion;
7911
0
    } else
7912
0
        ret = 1;
7913
0
      } else
7914
0
    ret = 1;
7915
0
      if (item != NULL)
7916
0
    xmlFree(item);
7917
0
      cur = end;
7918
0
  } while ((ret == 0) && (*cur != 0));
7919
0
    }
7920
7921
0
    return (ret);
7922
0
}
7923
7924
static int
7925
xmlSchemaCheckCSelectorXPath(xmlSchemaParserCtxtPtr ctxt,
7926
           xmlSchemaIDCPtr idc,
7927
           xmlSchemaIDCSelectPtr selector,
7928
           xmlAttrPtr attr,
7929
           int isField)
7930
0
{
7931
0
    xmlNodePtr node;
7932
7933
    /*
7934
    * c-selector-xpath:
7935
    * Schema Component Constraint: Selector Value OK
7936
    *
7937
    * TODO: 1 The {selector} must be a valid XPath expression, as defined
7938
    * in [XPath].
7939
    */
7940
0
    if (selector == NULL) {
7941
0
  xmlSchemaPErr(ctxt, idc->node,
7942
0
      XML_SCHEMAP_INTERNAL,
7943
0
      "Internal error: xmlSchemaCheckCSelectorXPath, "
7944
0
      "the selector is not specified.\n", NULL, NULL);
7945
0
  return (-1);
7946
0
    }
7947
0
    if (attr == NULL)
7948
0
  node = idc->node;
7949
0
    else
7950
0
  node = (xmlNodePtr) attr;
7951
0
    if (selector->xpath == NULL) {
7952
0
  xmlSchemaPCustomErr(ctxt,
7953
      /* TODO: Adjust error code. */
7954
0
      XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
7955
0
      NULL, node,
7956
0
      "The XPath expression of the selector is not valid", NULL);
7957
0
  return (XML_SCHEMAP_S4S_ATTR_INVALID_VALUE);
7958
0
    } else {
7959
0
  const xmlChar **nsArray = NULL;
7960
0
  xmlNsPtr *nsList = NULL;
7961
  /*
7962
  * Compile the XPath expression.
7963
  */
7964
  /*
7965
  * TODO: We need the array of in-scope namespaces for compilation.
7966
  * TODO: Call xmlPatterncompile with different options for selector/
7967
  * field.
7968
  */
7969
0
  if (attr == NULL)
7970
0
      nsList = NULL;
7971
0
  else
7972
0
      nsList = xmlGetNsList(attr->doc, attr->parent);
7973
  /*
7974
  * Build an array of prefixes and namespaces.
7975
  */
7976
0
  if (nsList != NULL) {
7977
0
      int i, count = 0;
7978
7979
0
      for (i = 0; nsList[i] != NULL; i++)
7980
0
    count++;
7981
7982
0
      nsArray = (const xmlChar **) xmlMalloc(
7983
0
    (count * 2 + 1) * sizeof(const xmlChar *));
7984
0
      if (nsArray == NULL) {
7985
0
    xmlSchemaPErrMemory(ctxt);
7986
0
    xmlFree(nsList);
7987
0
    return (-1);
7988
0
      }
7989
0
      for (i = 0; i < count; i++) {
7990
0
    nsArray[2 * i] = nsList[i]->href;
7991
0
    nsArray[2 * i + 1] = nsList[i]->prefix;
7992
0
      }
7993
0
      nsArray[count * 2] = NULL;
7994
0
      xmlFree(nsList);
7995
0
  }
7996
  /*
7997
  * TODO: Differentiate between "selector" and "field".
7998
  */
7999
0
  if (isField)
8000
0
      selector->xpathComp = (void *) xmlPatterncompile(selector->xpath,
8001
0
    NULL, XML_PATTERN_XSFIELD, nsArray);
8002
0
  else
8003
0
      selector->xpathComp = (void *) xmlPatterncompile(selector->xpath,
8004
0
    NULL, XML_PATTERN_XSSEL, nsArray);
8005
0
  if (nsArray != NULL)
8006
0
      xmlFree((xmlChar **) nsArray);
8007
8008
0
  if (selector->xpathComp == NULL) {
8009
0
      xmlSchemaPCustomErr(ctxt,
8010
    /* TODO: Adjust error code? */
8011
0
    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
8012
0
    NULL, node,
8013
0
    "The XPath expression '%s' could not be "
8014
0
    "compiled", selector->xpath);
8015
0
      return (XML_SCHEMAP_S4S_ATTR_INVALID_VALUE);
8016
0
  }
8017
0
    }
8018
0
    return (0);
8019
0
}
8020
8021
#define ADD_ANNOTATION(annot)   \
8022
0
    xmlSchemaAnnotPtr cur = item->annot; \
8023
0
    if (item->annot == NULL) {  \
8024
0
  item->annot = annot;    \
8025
0
  return (annot);         \
8026
0
    }                           \
8027
0
    cur = item->annot;          \
8028
0
    while (cur->next != NULL) { \
8029
0
  cur = cur->next;  \
8030
0
    }                           \
8031
0
    cur->next = annot;
8032
8033
/**
8034
 * xmlSchemaAssignAnnotation:
8035
 * @item: the schema component
8036
 * @annot: the annotation
8037
 *
8038
 * Adds the annotation to the given schema component.
8039
 *
8040
 * Returns the given annotation.
8041
 */
8042
static xmlSchemaAnnotPtr
8043
xmlSchemaAddAnnotation(xmlSchemaAnnotItemPtr annItem,
8044
           xmlSchemaAnnotPtr annot)
8045
0
{
8046
0
    if ((annItem == NULL) || (annot == NULL))
8047
0
  return (NULL);
8048
0
    switch (annItem->type) {
8049
0
  case XML_SCHEMA_TYPE_ELEMENT: {
8050
0
    xmlSchemaElementPtr item = (xmlSchemaElementPtr) annItem;
8051
0
    ADD_ANNOTATION(annot)
8052
0
      }
8053
0
      break;
8054
0
  case XML_SCHEMA_TYPE_ATTRIBUTE: {
8055
0
    xmlSchemaAttributePtr item = (xmlSchemaAttributePtr) annItem;
8056
0
    ADD_ANNOTATION(annot)
8057
0
      }
8058
0
      break;
8059
0
  case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
8060
0
  case XML_SCHEMA_TYPE_ANY: {
8061
0
    xmlSchemaWildcardPtr item = (xmlSchemaWildcardPtr) annItem;
8062
0
    ADD_ANNOTATION(annot)
8063
0
      }
8064
0
      break;
8065
0
  case XML_SCHEMA_TYPE_PARTICLE:
8066
0
  case XML_SCHEMA_TYPE_IDC_KEY:
8067
0
  case XML_SCHEMA_TYPE_IDC_KEYREF:
8068
0
  case XML_SCHEMA_TYPE_IDC_UNIQUE: {
8069
0
    xmlSchemaAnnotItemPtr item = (xmlSchemaAnnotItemPtr) annItem;
8070
0
    ADD_ANNOTATION(annot)
8071
0
      }
8072
0
      break;
8073
0
  case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: {
8074
0
    xmlSchemaAttributeGroupPtr item =
8075
0
        (xmlSchemaAttributeGroupPtr) annItem;
8076
0
    ADD_ANNOTATION(annot)
8077
0
      }
8078
0
      break;
8079
0
  case XML_SCHEMA_TYPE_NOTATION: {
8080
0
    xmlSchemaNotationPtr item = (xmlSchemaNotationPtr) annItem;
8081
0
    ADD_ANNOTATION(annot)
8082
0
      }
8083
0
      break;
8084
0
  case XML_SCHEMA_FACET_MININCLUSIVE:
8085
0
  case XML_SCHEMA_FACET_MINEXCLUSIVE:
8086
0
  case XML_SCHEMA_FACET_MAXINCLUSIVE:
8087
0
  case XML_SCHEMA_FACET_MAXEXCLUSIVE:
8088
0
  case XML_SCHEMA_FACET_TOTALDIGITS:
8089
0
  case XML_SCHEMA_FACET_FRACTIONDIGITS:
8090
0
  case XML_SCHEMA_FACET_PATTERN:
8091
0
  case XML_SCHEMA_FACET_ENUMERATION:
8092
0
  case XML_SCHEMA_FACET_WHITESPACE:
8093
0
  case XML_SCHEMA_FACET_LENGTH:
8094
0
  case XML_SCHEMA_FACET_MAXLENGTH:
8095
0
  case XML_SCHEMA_FACET_MINLENGTH: {
8096
0
    xmlSchemaFacetPtr item = (xmlSchemaFacetPtr) annItem;
8097
0
    ADD_ANNOTATION(annot)
8098
0
      }
8099
0
      break;
8100
0
  case XML_SCHEMA_TYPE_SIMPLE:
8101
0
  case XML_SCHEMA_TYPE_COMPLEX: {
8102
0
    xmlSchemaTypePtr item = (xmlSchemaTypePtr) annItem;
8103
0
    ADD_ANNOTATION(annot)
8104
0
      }
8105
0
      break;
8106
0
  case XML_SCHEMA_TYPE_GROUP: {
8107
0
    xmlSchemaModelGroupDefPtr item = (xmlSchemaModelGroupDefPtr) annItem;
8108
0
    ADD_ANNOTATION(annot)
8109
0
      }
8110
0
      break;
8111
0
  case XML_SCHEMA_TYPE_SEQUENCE:
8112
0
  case XML_SCHEMA_TYPE_CHOICE:
8113
0
  case XML_SCHEMA_TYPE_ALL: {
8114
0
    xmlSchemaModelGroupPtr item = (xmlSchemaModelGroupPtr) annItem;
8115
0
    ADD_ANNOTATION(annot)
8116
0
      }
8117
0
      break;
8118
0
  default:
8119
0
       xmlSchemaPCustomErr(NULL,
8120
0
    XML_SCHEMAP_INTERNAL,
8121
0
    NULL, NULL,
8122
0
    "Internal error: xmlSchemaAddAnnotation, "
8123
0
    "The item is not a annotated schema component", NULL);
8124
0
       break;
8125
0
    }
8126
0
    return (annot);
8127
0
}
8128
8129
/**
8130
 * xmlSchemaParseIDCSelectorAndField:
8131
 * @ctxt:  a schema validation context
8132
 * @schema:  the schema being built
8133
 * @node:  a subtree containing XML Schema information
8134
 *
8135
 * Parses a XML Schema identity-constraint definition's
8136
 * <selector> and <field> elements.
8137
 *
8138
 * Returns the parsed identity-constraint definition.
8139
 */
8140
static xmlSchemaIDCSelectPtr
8141
xmlSchemaParseIDCSelectorAndField(xmlSchemaParserCtxtPtr ctxt,
8142
        xmlSchemaIDCPtr idc,
8143
        xmlNodePtr node,
8144
        int isField)
8145
0
{
8146
0
    xmlSchemaIDCSelectPtr item;
8147
0
    xmlNodePtr child = NULL;
8148
0
    xmlAttrPtr attr;
8149
8150
    /*
8151
    * Check for illegal attributes.
8152
    */
8153
0
    attr = node->properties;
8154
0
    while (attr != NULL) {
8155
0
  if (attr->ns == NULL) {
8156
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
8157
0
    (!xmlStrEqual(attr->name, BAD_CAST "xpath"))) {
8158
0
    xmlSchemaPIllegalAttrErr(ctxt,
8159
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
8160
0
      }
8161
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
8162
0
      xmlSchemaPIllegalAttrErr(ctxt,
8163
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
8164
0
  }
8165
0
  attr = attr->next;
8166
0
    }
8167
    /*
8168
    * Create the item.
8169
    */
8170
0
    item = (xmlSchemaIDCSelectPtr) xmlMalloc(sizeof(xmlSchemaIDCSelect));
8171
0
    if (item == NULL) {
8172
0
        xmlSchemaPErrMemory(ctxt);
8173
0
        return (NULL);
8174
0
    }
8175
0
    memset(item, 0, sizeof(xmlSchemaIDCSelect));
8176
    /*
8177
    * Attribute "xpath" (mandatory).
8178
    */
8179
0
    attr = xmlSchemaGetPropNode(node, "xpath");
8180
0
    if (attr == NULL) {
8181
0
  xmlSchemaPMissingAttrErr(ctxt,
8182
0
      XML_SCHEMAP_S4S_ATTR_MISSING,
8183
0
      NULL, node,
8184
0
      "name", NULL);
8185
0
    } else {
8186
0
  item->xpath = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
8187
  /*
8188
  * URGENT TODO: "field"s have an other syntax than "selector"s.
8189
  */
8190
8191
0
  if (xmlSchemaCheckCSelectorXPath(ctxt, idc, item, attr,
8192
0
      isField) == -1) {
8193
0
      xmlSchemaPErr(ctxt,
8194
0
    (xmlNodePtr) attr,
8195
0
    XML_SCHEMAP_INTERNAL,
8196
0
    "Internal error: xmlSchemaParseIDCSelectorAndField, "
8197
0
    "validating the XPath expression of a IDC selector.\n",
8198
0
    NULL, NULL);
8199
0
  }
8200
8201
0
    }
8202
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
8203
    /*
8204
    * And now for the children...
8205
    */
8206
0
    child = node->children;
8207
0
    if (IS_SCHEMA(child, "annotation")) {
8208
  /*
8209
  * Add the annotation to the parent IDC.
8210
  */
8211
0
  xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) idc,
8212
0
      xmlSchemaParseAnnotation(ctxt, child, 1));
8213
0
  child = child->next;
8214
0
    }
8215
0
    if (child != NULL) {
8216
0
  xmlSchemaPContentErr(ctxt,
8217
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
8218
0
      NULL, node, child,
8219
0
      NULL, "(annotation?)");
8220
0
    }
8221
8222
0
    return (item);
8223
0
}
8224
8225
/**
8226
 * xmlSchemaParseIDC:
8227
 * @ctxt:  a schema validation context
8228
 * @schema:  the schema being built
8229
 * @node:  a subtree containing XML Schema information
8230
 *
8231
 * Parses a XML Schema identity-constraint definition.
8232
 *
8233
 * Returns the parsed identity-constraint definition.
8234
 */
8235
static xmlSchemaIDCPtr
8236
xmlSchemaParseIDC(xmlSchemaParserCtxtPtr ctxt,
8237
      xmlSchemaPtr schema,
8238
      xmlNodePtr node,
8239
      xmlSchemaTypeType idcCategory,
8240
      const xmlChar *targetNamespace)
8241
0
{
8242
0
    xmlSchemaIDCPtr item = NULL;
8243
0
    xmlNodePtr child = NULL;
8244
0
    xmlAttrPtr attr;
8245
0
    const xmlChar *name = NULL;
8246
0
    xmlSchemaIDCSelectPtr field = NULL, lastField = NULL;
8247
8248
    /*
8249
    * Check for illegal attributes.
8250
    */
8251
0
    attr = node->properties;
8252
0
    while (attr != NULL) {
8253
0
  if (attr->ns == NULL) {
8254
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
8255
0
    (!xmlStrEqual(attr->name, BAD_CAST "name")) &&
8256
0
    ((idcCategory != XML_SCHEMA_TYPE_IDC_KEYREF) ||
8257
0
     (!xmlStrEqual(attr->name, BAD_CAST "refer")))) {
8258
0
    xmlSchemaPIllegalAttrErr(ctxt,
8259
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
8260
0
      }
8261
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
8262
0
      xmlSchemaPIllegalAttrErr(ctxt,
8263
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
8264
0
  }
8265
0
  attr = attr->next;
8266
0
    }
8267
    /*
8268
    * Attribute "name" (mandatory).
8269
    */
8270
0
    attr = xmlSchemaGetPropNode(node, "name");
8271
0
    if (attr == NULL) {
8272
0
  xmlSchemaPMissingAttrErr(ctxt,
8273
0
      XML_SCHEMAP_S4S_ATTR_MISSING,
8274
0
      NULL, node,
8275
0
      "name", NULL);
8276
0
  return (NULL);
8277
0
    } else if (xmlSchemaPValAttrNode(ctxt,
8278
0
  NULL, attr,
8279
0
  xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
8280
0
  return (NULL);
8281
0
    }
8282
    /* Create the component. */
8283
0
    item = xmlSchemaAddIDC(ctxt, schema, name, targetNamespace,
8284
0
  idcCategory, node);
8285
0
    if (item == NULL)
8286
0
  return(NULL);
8287
8288
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
8289
0
    if (idcCategory == XML_SCHEMA_TYPE_IDC_KEYREF) {
8290
  /*
8291
  * Attribute "refer" (mandatory).
8292
  */
8293
0
  attr = xmlSchemaGetPropNode(node, "refer");
8294
0
  if (attr == NULL) {
8295
0
      xmlSchemaPMissingAttrErr(ctxt,
8296
0
    XML_SCHEMAP_S4S_ATTR_MISSING,
8297
0
    NULL, node,
8298
0
    "refer", NULL);
8299
0
  } else {
8300
      /*
8301
      * Create a reference item.
8302
      */
8303
0
      item->ref = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_IDC_KEY,
8304
0
    NULL, NULL);
8305
0
      if (item->ref == NULL)
8306
0
    return (NULL);
8307
0
      xmlSchemaPValAttrNodeQName(ctxt, schema,
8308
0
    NULL, attr,
8309
0
    &(item->ref->targetNamespace),
8310
0
    &(item->ref->name));
8311
0
      xmlSchemaCheckReference(ctxt, schema, node, attr,
8312
0
    item->ref->targetNamespace);
8313
0
  }
8314
0
    }
8315
    /*
8316
    * And now for the children...
8317
    */
8318
0
    child = node->children;
8319
0
    if (IS_SCHEMA(child, "annotation")) {
8320
0
  item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
8321
0
  child = child->next;
8322
0
    }
8323
0
    if (child == NULL) {
8324
0
  xmlSchemaPContentErr(ctxt,
8325
0
    XML_SCHEMAP_S4S_ELEM_MISSING,
8326
0
    NULL, node, child,
8327
0
    "A child element is missing",
8328
0
    "(annotation?, (selector, field+))");
8329
0
    }
8330
    /*
8331
    * Child element <selector>.
8332
    */
8333
0
    if (IS_SCHEMA(child, "selector")) {
8334
0
  item->selector = xmlSchemaParseIDCSelectorAndField(ctxt,
8335
0
      item, child, 0);
8336
0
  child = child->next;
8337
  /*
8338
  * Child elements <field>.
8339
  */
8340
0
  if (IS_SCHEMA(child, "field")) {
8341
0
      do {
8342
0
    field = xmlSchemaParseIDCSelectorAndField(ctxt,
8343
0
        item, child, 1);
8344
0
    if (field != NULL) {
8345
0
        field->index = item->nbFields;
8346
0
        item->nbFields++;
8347
0
        if (lastField != NULL)
8348
0
      lastField->next = field;
8349
0
        else
8350
0
      item->fields = field;
8351
0
        lastField = field;
8352
0
    }
8353
0
    child = child->next;
8354
0
      } while (IS_SCHEMA(child, "field"));
8355
0
  } else {
8356
0
      xmlSchemaPContentErr(ctxt,
8357
0
    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
8358
0
    NULL, node, child,
8359
0
    NULL, "(annotation?, (selector, field+))");
8360
0
  }
8361
0
    }
8362
0
    if (child != NULL) {
8363
0
  xmlSchemaPContentErr(ctxt,
8364
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
8365
0
      NULL, node, child,
8366
0
      NULL, "(annotation?, (selector, field+))");
8367
0
    }
8368
8369
0
    return (item);
8370
0
}
8371
8372
/**
8373
 * xmlSchemaParseElement:
8374
 * @ctxt:  a schema validation context
8375
 * @schema:  the schema being built
8376
 * @node:  a subtree containing XML Schema information
8377
 * @topLevel: indicates if this is global declaration
8378
 *
8379
 * Parses a XML schema element declaration.
8380
 * *WARNING* this interface is highly subject to change
8381
 *
8382
 * Returns the element declaration or a particle; NULL in case
8383
 * of an error or if the particle has minOccurs==maxOccurs==0.
8384
 */
8385
static xmlSchemaBasicItemPtr
8386
xmlSchemaParseElement(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
8387
                      xmlNodePtr node, int *isElemRef, int topLevel)
8388
0
{
8389
0
    xmlSchemaElementPtr decl = NULL;
8390
0
    xmlSchemaParticlePtr particle = NULL;
8391
0
    xmlSchemaAnnotPtr annot = NULL;
8392
0
    xmlNodePtr child = NULL;
8393
0
    xmlAttrPtr attr, nameAttr;
8394
0
    int min, max, isRef = 0;
8395
0
    xmlChar *des = NULL;
8396
8397
    /* 3.3.3 Constraints on XML Representations of Element Declarations */
8398
    /* TODO: Complete implementation of 3.3.6 */
8399
8400
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
8401
0
        return (NULL);
8402
8403
0
    if (isElemRef != NULL)
8404
0
  *isElemRef = 0;
8405
    /*
8406
    * If we get a "ref" attribute on a local <element> we will assume it's
8407
    * a reference - even if there's a "name" attribute; this seems to be more
8408
    * robust.
8409
    */
8410
0
    nameAttr = xmlSchemaGetPropNode(node, "name");
8411
0
    attr = xmlSchemaGetPropNode(node, "ref");
8412
0
    if ((topLevel) || (attr == NULL)) {
8413
0
  if (nameAttr == NULL) {
8414
0
      xmlSchemaPMissingAttrErr(ctxt,
8415
0
    XML_SCHEMAP_S4S_ATTR_MISSING,
8416
0
    NULL, node, "name", NULL);
8417
0
      return (NULL);
8418
0
  }
8419
0
    } else
8420
0
  isRef = 1;
8421
8422
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
8423
0
    child = node->children;
8424
0
    if (IS_SCHEMA(child, "annotation")) {
8425
0
  annot = xmlSchemaParseAnnotation(ctxt, child, 1);
8426
0
  child = child->next;
8427
0
    }
8428
    /*
8429
    * Skip particle part if a global declaration.
8430
    */
8431
0
    if (topLevel)
8432
0
  goto declaration_part;
8433
    /*
8434
    * The particle part ==================================================
8435
    */
8436
0
    min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger");
8437
0
    max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1, "(xs:nonNegativeInteger | unbounded)");
8438
0
    xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max);
8439
0
    particle = xmlSchemaAddParticle(ctxt, node, min, max);
8440
0
    if (particle == NULL)
8441
0
  goto return_null;
8442
8443
    /* ret->flags |= XML_SCHEMAS_ELEM_REF; */
8444
8445
0
    if (isRef) {
8446
0
  const xmlChar *refNs = NULL, *ref = NULL;
8447
0
  xmlSchemaQNameRefPtr refer = NULL;
8448
  /*
8449
  * The reference part =============================================
8450
  */
8451
0
  if (isElemRef != NULL)
8452
0
      *isElemRef = 1;
8453
8454
0
  xmlSchemaPValAttrNodeQName(ctxt, schema,
8455
0
      NULL, attr, &refNs, &ref);
8456
0
  xmlSchemaCheckReference(ctxt, schema, node, attr, refNs);
8457
  /*
8458
  * SPEC (3.3.3 : 2.1) "One of ref or name must be present, but not both"
8459
  */
8460
0
  if (nameAttr != NULL) {
8461
0
      xmlSchemaPMutualExclAttrErr(ctxt,
8462
0
    XML_SCHEMAP_SRC_ELEMENT_2_1, NULL, nameAttr, "ref", "name");
8463
0
  }
8464
  /*
8465
  * Check for illegal attributes.
8466
  */
8467
0
  attr = node->properties;
8468
0
  while (attr != NULL) {
8469
0
      if (attr->ns == NULL) {
8470
0
    if (xmlStrEqual(attr->name, BAD_CAST "ref") ||
8471
0
        xmlStrEqual(attr->name, BAD_CAST "name") ||
8472
0
        xmlStrEqual(attr->name, BAD_CAST "id") ||
8473
0
        xmlStrEqual(attr->name, BAD_CAST "maxOccurs") ||
8474
0
        xmlStrEqual(attr->name, BAD_CAST "minOccurs"))
8475
0
    {
8476
0
        attr = attr->next;
8477
0
        continue;
8478
0
    } else {
8479
        /* SPEC (3.3.3 : 2.2) */
8480
0
        xmlSchemaPCustomAttrErr(ctxt,
8481
0
      XML_SCHEMAP_SRC_ELEMENT_2_2,
8482
0
      NULL, NULL, attr,
8483
0
      "Only the attributes 'minOccurs', 'maxOccurs' and "
8484
0
      "'id' are allowed in addition to 'ref'");
8485
0
        break;
8486
0
    }
8487
0
      } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
8488
0
    xmlSchemaPIllegalAttrErr(ctxt,
8489
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
8490
0
      }
8491
0
      attr = attr->next;
8492
0
  }
8493
  /*
8494
  * No children except <annotation> expected.
8495
  */
8496
0
  if (child != NULL) {
8497
0
      xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
8498
0
    NULL, node, child, NULL, "(annotation?)");
8499
0
  }
8500
0
  if ((min == 0) && (max == 0))
8501
0
      goto return_null;
8502
  /*
8503
  * Create the reference item and attach it to the particle.
8504
  */
8505
0
  refer = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_ELEMENT,
8506
0
      ref, refNs);
8507
0
  if (refer == NULL)
8508
0
      goto return_null;
8509
0
  particle->children = (xmlSchemaTreeItemPtr) refer;
8510
0
  particle->annot = annot;
8511
  /*
8512
  * Add the particle to pending components, since the reference
8513
  * need to be resolved.
8514
  */
8515
0
  WXS_ADD_PENDING(ctxt, particle);
8516
0
  return ((xmlSchemaBasicItemPtr) particle);
8517
0
    }
8518
    /*
8519
    * The declaration part ===============================================
8520
    */
8521
0
declaration_part:
8522
0
    {
8523
0
  const xmlChar *ns = NULL, *fixed, *name, *attrValue;
8524
0
  xmlSchemaIDCPtr curIDC = NULL, lastIDC = NULL;
8525
8526
0
  if (xmlSchemaPValAttrNode(ctxt, NULL, nameAttr,
8527
0
      xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0)
8528
0
      goto return_null;
8529
  /*
8530
  * Evaluate the target namespace.
8531
  */
8532
0
  if (topLevel) {
8533
0
      ns = ctxt->targetNamespace;
8534
0
  } else {
8535
0
      attr = xmlSchemaGetPropNode(node, "form");
8536
0
      if (attr != NULL) {
8537
0
    attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
8538
0
    if (xmlStrEqual(attrValue, BAD_CAST "qualified")) {
8539
0
        ns = ctxt->targetNamespace;
8540
0
    } else if (!xmlStrEqual(attrValue, BAD_CAST "unqualified")) {
8541
0
        xmlSchemaPSimpleTypeErr(ctxt,
8542
0
      XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
8543
0
      NULL, (xmlNodePtr) attr,
8544
0
      NULL, "(qualified | unqualified)",
8545
0
      attrValue, NULL, NULL, NULL);
8546
0
    }
8547
0
      } else if (schema->flags & XML_SCHEMAS_QUALIF_ELEM)
8548
0
    ns = ctxt->targetNamespace;
8549
0
  }
8550
0
  decl = xmlSchemaAddElement(ctxt, name, ns, node, topLevel);
8551
0
  if (decl == NULL) {
8552
0
      goto return_null;
8553
0
  }
8554
  /*
8555
  * Check for illegal attributes.
8556
  */
8557
0
  attr = node->properties;
8558
0
  while (attr != NULL) {
8559
0
      if (attr->ns == NULL) {
8560
0
    if ((!xmlStrEqual(attr->name, BAD_CAST "name")) &&
8561
0
        (!xmlStrEqual(attr->name, BAD_CAST "type")) &&
8562
0
        (!xmlStrEqual(attr->name, BAD_CAST "id")) &&
8563
0
        (!xmlStrEqual(attr->name, BAD_CAST "default")) &&
8564
0
        (!xmlStrEqual(attr->name, BAD_CAST "fixed")) &&
8565
0
        (!xmlStrEqual(attr->name, BAD_CAST "block")) &&
8566
0
        (!xmlStrEqual(attr->name, BAD_CAST "nillable")))
8567
0
    {
8568
0
        if (topLevel == 0) {
8569
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) &&
8570
0
          (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) &&
8571
0
          (!xmlStrEqual(attr->name, BAD_CAST "form")))
8572
0
      {
8573
0
          xmlSchemaPIllegalAttrErr(ctxt,
8574
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
8575
0
      }
8576
0
        } else if ((!xmlStrEqual(attr->name, BAD_CAST "final")) &&
8577
0
      (!xmlStrEqual(attr->name, BAD_CAST "abstract")) &&
8578
0
      (!xmlStrEqual(attr->name, BAD_CAST "substitutionGroup"))) {
8579
8580
0
      xmlSchemaPIllegalAttrErr(ctxt,
8581
0
          XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
8582
0
        }
8583
0
    }
8584
0
      } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
8585
8586
0
    xmlSchemaPIllegalAttrErr(ctxt,
8587
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
8588
0
      }
8589
0
      attr = attr->next;
8590
0
  }
8591
  /*
8592
  * Extract/validate attributes.
8593
  */
8594
0
  if (topLevel) {
8595
      /*
8596
      * Process top attributes of global element declarations here.
8597
      */
8598
0
      decl->flags |= XML_SCHEMAS_ELEM_GLOBAL;
8599
0
      decl->flags |= XML_SCHEMAS_ELEM_TOPLEVEL;
8600
0
      xmlSchemaPValAttrQName(ctxt, schema,
8601
0
    NULL, node, "substitutionGroup",
8602
0
    &(decl->substGroupNs), &(decl->substGroup));
8603
0
      if (xmlGetBooleanProp(ctxt, node, "abstract", 0))
8604
0
    decl->flags |= XML_SCHEMAS_ELEM_ABSTRACT;
8605
      /*
8606
      * Attribute "final".
8607
      */
8608
0
      attr = xmlSchemaGetPropNode(node, "final");
8609
0
      if (attr == NULL) {
8610
0
    if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION)
8611
0
        decl->flags |= XML_SCHEMAS_ELEM_FINAL_EXTENSION;
8612
0
    if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
8613
0
        decl->flags |= XML_SCHEMAS_ELEM_FINAL_RESTRICTION;
8614
0
      } else {
8615
0
    attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
8616
0
    if (xmlSchemaPValAttrBlockFinal(attrValue, &(decl->flags),
8617
0
        -1,
8618
0
        XML_SCHEMAS_ELEM_FINAL_EXTENSION,
8619
0
        XML_SCHEMAS_ELEM_FINAL_RESTRICTION, -1, -1, -1) != 0) {
8620
0
        xmlSchemaPSimpleTypeErr(ctxt,
8621
0
      XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
8622
0
      NULL, (xmlNodePtr) attr,
8623
0
      NULL, "(#all | List of (extension | restriction))",
8624
0
      attrValue, NULL, NULL, NULL);
8625
0
    }
8626
0
      }
8627
0
  }
8628
  /*
8629
  * Attribute "block".
8630
  */
8631
0
  attr = xmlSchemaGetPropNode(node, "block");
8632
0
  if (attr == NULL) {
8633
      /*
8634
      * Apply default "block" values.
8635
      */
8636
0
      if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION)
8637
0
    decl->flags |= XML_SCHEMAS_ELEM_BLOCK_RESTRICTION;
8638
0
      if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION)
8639
0
    decl->flags |= XML_SCHEMAS_ELEM_BLOCK_EXTENSION;
8640
0
      if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION)
8641
0
    decl->flags |= XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION;
8642
0
  } else {
8643
0
      attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
8644
0
      if (xmlSchemaPValAttrBlockFinal(attrValue, &(decl->flags),
8645
0
    -1,
8646
0
    XML_SCHEMAS_ELEM_BLOCK_EXTENSION,
8647
0
    XML_SCHEMAS_ELEM_BLOCK_RESTRICTION,
8648
0
    XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION, -1, -1) != 0) {
8649
0
    xmlSchemaPSimpleTypeErr(ctxt,
8650
0
        XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
8651
0
        NULL, (xmlNodePtr) attr,
8652
0
        NULL, "(#all | List of (extension | "
8653
0
        "restriction | substitution))", attrValue,
8654
0
        NULL, NULL, NULL);
8655
0
      }
8656
0
  }
8657
0
  if (xmlGetBooleanProp(ctxt, node, "nillable", 0))
8658
0
      decl->flags |= XML_SCHEMAS_ELEM_NILLABLE;
8659
8660
0
  attr = xmlSchemaGetPropNode(node, "type");
8661
0
  if (attr != NULL) {
8662
0
      xmlSchemaPValAttrNodeQName(ctxt, schema,
8663
0
    NULL, attr,
8664
0
    &(decl->namedTypeNs), &(decl->namedType));
8665
0
      xmlSchemaCheckReference(ctxt, schema, node,
8666
0
    attr, decl->namedTypeNs);
8667
0
  }
8668
0
  decl->value = xmlSchemaGetProp(ctxt, node, "default");
8669
0
  attr = xmlSchemaGetPropNode(node, "fixed");
8670
0
  if (attr != NULL) {
8671
0
      fixed = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
8672
0
      if (decl->value != NULL) {
8673
    /*
8674
    * 3.3.3 : 1
8675
    * default and fixed must not both be present.
8676
    */
8677
0
    xmlSchemaPMutualExclAttrErr(ctxt,
8678
0
        XML_SCHEMAP_SRC_ELEMENT_1,
8679
0
        NULL, attr, "default", "fixed");
8680
0
      } else {
8681
0
    decl->flags |= XML_SCHEMAS_ELEM_FIXED;
8682
0
    decl->value = fixed;
8683
0
      }
8684
0
  }
8685
  /*
8686
  * And now for the children...
8687
  */
8688
0
  if (IS_SCHEMA(child, "complexType")) {
8689
      /*
8690
      * 3.3.3 : 3
8691
      * "type" and either <simpleType> or <complexType> are mutually
8692
      * exclusive
8693
      */
8694
0
      if (decl->namedType != NULL) {
8695
0
    xmlSchemaPContentErr(ctxt,
8696
0
        XML_SCHEMAP_SRC_ELEMENT_3,
8697
0
        NULL, node, child,
8698
0
        "The attribute 'type' and the <complexType> child are "
8699
0
        "mutually exclusive", NULL);
8700
0
      } else
8701
0
    WXS_ELEM_TYPEDEF(decl) = xmlSchemaParseComplexType(ctxt, schema, child, 0);
8702
0
      child = child->next;
8703
0
  } else if (IS_SCHEMA(child, "simpleType")) {
8704
      /*
8705
      * 3.3.3 : 3
8706
      * "type" and either <simpleType> or <complexType> are
8707
      * mutually exclusive
8708
      */
8709
0
      if (decl->namedType != NULL) {
8710
0
    xmlSchemaPContentErr(ctxt,
8711
0
        XML_SCHEMAP_SRC_ELEMENT_3,
8712
0
        NULL, node, child,
8713
0
        "The attribute 'type' and the <simpleType> child are "
8714
0
        "mutually exclusive", NULL);
8715
0
      } else
8716
0
    WXS_ELEM_TYPEDEF(decl) = xmlSchemaParseSimpleType(ctxt, schema, child, 0);
8717
0
      child = child->next;
8718
0
  }
8719
0
  while ((IS_SCHEMA(child, "unique")) ||
8720
0
      (IS_SCHEMA(child, "key")) || (IS_SCHEMA(child, "keyref"))) {
8721
0
      if (IS_SCHEMA(child, "unique")) {
8722
0
    curIDC = xmlSchemaParseIDC(ctxt, schema, child,
8723
0
        XML_SCHEMA_TYPE_IDC_UNIQUE, decl->targetNamespace);
8724
0
      } else if (IS_SCHEMA(child, "key")) {
8725
0
    curIDC = xmlSchemaParseIDC(ctxt, schema, child,
8726
0
        XML_SCHEMA_TYPE_IDC_KEY, decl->targetNamespace);
8727
0
      } else if (IS_SCHEMA(child, "keyref")) {
8728
0
    curIDC = xmlSchemaParseIDC(ctxt, schema, child,
8729
0
        XML_SCHEMA_TYPE_IDC_KEYREF, decl->targetNamespace);
8730
0
      }
8731
0
      if (lastIDC != NULL)
8732
0
    lastIDC->next = curIDC;
8733
0
      else
8734
0
    decl->idcs = (void *) curIDC;
8735
0
      lastIDC = curIDC;
8736
0
      child = child->next;
8737
0
  }
8738
0
  if (child != NULL) {
8739
0
      xmlSchemaPContentErr(ctxt,
8740
0
    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
8741
0
    NULL, node, child,
8742
0
    NULL, "(annotation?, ((simpleType | complexType)?, "
8743
0
    "(unique | key | keyref)*))");
8744
0
  }
8745
0
  decl->annot = annot;
8746
0
    }
8747
    /*
8748
    * NOTE: Element Declaration Representation OK 4. will be checked at a
8749
    * different layer.
8750
    */
8751
0
    FREE_AND_NULL(des)
8752
0
    if (topLevel)
8753
0
  return ((xmlSchemaBasicItemPtr) decl);
8754
0
    else {
8755
0
  particle->children = (xmlSchemaTreeItemPtr) decl;
8756
0
  return ((xmlSchemaBasicItemPtr) particle);
8757
0
    }
8758
8759
0
return_null:
8760
0
    FREE_AND_NULL(des);
8761
0
    if (annot != NULL) {
8762
0
  if (particle != NULL)
8763
0
      particle->annot = NULL;
8764
0
  if (decl != NULL)
8765
0
      decl->annot = NULL;
8766
0
  xmlSchemaFreeAnnot(annot);
8767
0
    }
8768
0
    return (NULL);
8769
0
}
8770
8771
/**
8772
 * xmlSchemaParseUnion:
8773
 * @ctxt:  a schema validation context
8774
 * @schema:  the schema being built
8775
 * @node:  a subtree containing XML Schema information
8776
 *
8777
 * parse a XML schema Union definition
8778
 * *WARNING* this interface is highly subject to change
8779
 *
8780
 * Returns -1 in case of internal error, 0 in case of success and a positive
8781
 * error code otherwise.
8782
 */
8783
static int
8784
xmlSchemaParseUnion(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
8785
                    xmlNodePtr node)
8786
0
{
8787
0
    xmlSchemaTypePtr type;
8788
0
    xmlNodePtr child = NULL;
8789
0
    xmlAttrPtr attr;
8790
0
    const xmlChar *cur = NULL;
8791
8792
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
8793
0
        return (-1);
8794
    /* Not a component, don't create it. */
8795
0
    type = ctxt->ctxtType;
8796
    /*
8797
    * Mark the simple type as being of variety "union".
8798
    */
8799
0
    type->flags |= XML_SCHEMAS_TYPE_VARIETY_UNION;
8800
    /*
8801
    * SPEC (Base type) (2) "If the <list> or <union> alternative is chosen,
8802
    * then the `simple ur-type definition`."
8803
    */
8804
0
    type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
8805
    /*
8806
    * Check for illegal attributes.
8807
    */
8808
0
    attr = node->properties;
8809
0
    while (attr != NULL) {
8810
0
  if (attr->ns == NULL) {
8811
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
8812
0
    (!xmlStrEqual(attr->name, BAD_CAST "memberTypes"))) {
8813
0
    xmlSchemaPIllegalAttrErr(ctxt,
8814
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
8815
0
      }
8816
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
8817
0
      xmlSchemaPIllegalAttrErr(ctxt,
8818
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
8819
0
  }
8820
0
  attr = attr->next;
8821
0
    }
8822
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
8823
    /*
8824
    * Attribute "memberTypes". This is a list of QNames.
8825
    * TODO: Check the value to contain anything.
8826
    */
8827
0
    attr = xmlSchemaGetPropNode(node, "memberTypes");
8828
0
    if (attr != NULL) {
8829
0
  const xmlChar *end;
8830
0
  xmlChar *tmp;
8831
0
  const xmlChar *localName, *nsName;
8832
0
  xmlSchemaTypeLinkPtr link, lastLink = NULL;
8833
0
  xmlSchemaQNameRefPtr ref;
8834
8835
0
  cur = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
8836
0
        if (cur == NULL)
8837
0
            return (-1);
8838
0
  type->base = cur;
8839
0
  do {
8840
0
      while (IS_BLANK_CH(*cur))
8841
0
    cur++;
8842
0
      end = cur;
8843
0
      while ((*end != 0) && (!(IS_BLANK_CH(*end))))
8844
0
    end++;
8845
0
      if (end == cur)
8846
0
    break;
8847
0
      tmp = xmlStrndup(cur, end - cur);
8848
0
            if (tmp == NULL) {
8849
0
                xmlSchemaPErrMemory(ctxt);
8850
0
                return (-1);
8851
0
            }
8852
0
      if (xmlSchemaPValAttrNodeQNameValue(ctxt, schema,
8853
0
    NULL, attr, BAD_CAST tmp, &nsName, &localName) == 0) {
8854
    /*
8855
    * Create the member type link.
8856
    */
8857
0
    link = (xmlSchemaTypeLinkPtr)
8858
0
        xmlMalloc(sizeof(xmlSchemaTypeLink));
8859
0
    if (link == NULL) {
8860
0
        xmlSchemaPErrMemory(ctxt);
8861
0
              FREE_AND_NULL(tmp)
8862
0
        return (-1);
8863
0
    }
8864
0
    link->type = NULL;
8865
0
    link->next = NULL;
8866
    /*
8867
    * Create a reference item.
8868
    */
8869
0
    ref = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_SIMPLE,
8870
0
        localName, nsName);
8871
0
    if (ref == NULL) {
8872
0
                    xmlSchemaPErrMemory(ctxt);
8873
0
                    xmlFree(link);
8874
0
        FREE_AND_NULL(tmp)
8875
0
        return (-1);
8876
0
    }
8877
    /*
8878
    * Assign the reference to the link, it will be resolved
8879
    * later during fixup of the union simple type.
8880
    */
8881
0
    link->type = (xmlSchemaTypePtr) ref;
8882
8883
0
    if (lastLink == NULL)
8884
0
        type->memberTypes = link;
8885
0
    else
8886
0
        lastLink->next = link;
8887
0
    lastLink = link;
8888
0
      }
8889
0
      FREE_AND_NULL(tmp)
8890
0
      cur = end;
8891
0
  } while (*cur != 0);
8892
8893
0
    }
8894
    /*
8895
    * And now for the children...
8896
    */
8897
0
    child = node->children;
8898
0
    if (IS_SCHEMA(child, "annotation")) {
8899
  /*
8900
  * Add the annotation to the simple type ancestor.
8901
  */
8902
0
  xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
8903
0
      xmlSchemaParseAnnotation(ctxt, child, 1));
8904
0
        child = child->next;
8905
0
    }
8906
0
    if (IS_SCHEMA(child, "simpleType")) {
8907
0
  xmlSchemaTypePtr subtype, last = NULL;
8908
8909
  /*
8910
  * Anchor the member types in the "subtypes" field of the
8911
  * simple type.
8912
  */
8913
0
  while (IS_SCHEMA(child, "simpleType")) {
8914
0
      subtype = (xmlSchemaTypePtr)
8915
0
    xmlSchemaParseSimpleType(ctxt, schema, child, 0);
8916
0
      if (subtype != NULL) {
8917
0
    if (last == NULL) {
8918
0
        type->subtypes = subtype;
8919
0
        last = subtype;
8920
0
    } else {
8921
0
        last->next = subtype;
8922
0
        last = subtype;
8923
0
    }
8924
0
    last->next = NULL;
8925
0
      }
8926
0
      child = child->next;
8927
0
  }
8928
0
    }
8929
0
    if (child != NULL) {
8930
0
  xmlSchemaPContentErr(ctxt,
8931
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
8932
0
      NULL, node, child, NULL, "(annotation?, simpleType*)");
8933
0
    }
8934
0
    if ((attr == NULL) && (type->subtypes == NULL)) {
8935
   /*
8936
  * src-union-memberTypes-or-simpleTypes
8937
  * Either the memberTypes [attribute] of the <union> element must
8938
  * be non-empty or there must be at least one simpleType [child].
8939
  */
8940
0
  xmlSchemaPCustomErr(ctxt,
8941
0
      XML_SCHEMAP_SRC_UNION_MEMBERTYPES_OR_SIMPLETYPES,
8942
0
      NULL, node,
8943
0
      "Either the attribute 'memberTypes' or "
8944
0
      "at least one <simpleType> child must be present", NULL);
8945
0
    }
8946
0
    return (0);
8947
0
}
8948
8949
/**
8950
 * xmlSchemaParseList:
8951
 * @ctxt:  a schema validation context
8952
 * @schema:  the schema being built
8953
 * @node:  a subtree containing XML Schema information
8954
 *
8955
 * parse a XML schema List definition
8956
 * *WARNING* this interface is highly subject to change
8957
 *
8958
 * Returns -1 in case of error, 0 if the declaration is improper and
8959
 *         1 in case of success.
8960
 */
8961
static xmlSchemaTypePtr
8962
xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
8963
                   xmlNodePtr node)
8964
0
{
8965
0
    xmlSchemaTypePtr type;
8966
0
    xmlNodePtr child = NULL;
8967
0
    xmlAttrPtr attr;
8968
8969
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
8970
0
        return (NULL);
8971
    /* Not a component, don't create it. */
8972
0
    type = ctxt->ctxtType;
8973
    /*
8974
    * Mark the type as being of variety "list".
8975
    */
8976
0
    type->flags |= XML_SCHEMAS_TYPE_VARIETY_LIST;
8977
    /*
8978
    * SPEC (Base type) (2) "If the <list> or <union> alternative is chosen,
8979
    * then the `simple ur-type definition`."
8980
    */
8981
0
    type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
8982
    /*
8983
    * Check for illegal attributes.
8984
    */
8985
0
    attr = node->properties;
8986
0
    while (attr != NULL) {
8987
0
  if (attr->ns == NULL) {
8988
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
8989
0
    (!xmlStrEqual(attr->name, BAD_CAST "itemType"))) {
8990
0
    xmlSchemaPIllegalAttrErr(ctxt,
8991
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
8992
0
      }
8993
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
8994
0
      xmlSchemaPIllegalAttrErr(ctxt,
8995
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
8996
0
  }
8997
0
  attr = attr->next;
8998
0
    }
8999
9000
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
9001
9002
    /*
9003
    * Attribute "itemType". NOTE that we will use the "ref" and "refNs"
9004
    * fields for holding the reference to the itemType.
9005
    *
9006
    * REVAMP TODO: Use the "base" and "baseNs" fields, since we will remove
9007
    * the "ref" fields.
9008
    */
9009
0
    xmlSchemaPValAttrQName(ctxt, schema, NULL,
9010
0
  node, "itemType", &(type->baseNs), &(type->base));
9011
    /*
9012
    * And now for the children...
9013
    */
9014
0
    child = node->children;
9015
0
    if (IS_SCHEMA(child, "annotation")) {
9016
0
  xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
9017
0
      xmlSchemaParseAnnotation(ctxt, child, 1));
9018
0
        child = child->next;
9019
0
    }
9020
0
    if (IS_SCHEMA(child, "simpleType")) {
9021
  /*
9022
  * src-list-itemType-or-simpleType
9023
  * Either the itemType [attribute] or the <simpleType> [child] of
9024
  * the <list> element must be present, but not both.
9025
  */
9026
0
  if (type->base != NULL) {
9027
0
      xmlSchemaPCustomErr(ctxt,
9028
0
    XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
9029
0
    NULL, node,
9030
0
    "The attribute 'itemType' and the <simpleType> child "
9031
0
    "are mutually exclusive", NULL);
9032
0
  } else {
9033
0
      type->subtypes = xmlSchemaParseSimpleType(ctxt, schema, child, 0);
9034
0
  }
9035
0
        child = child->next;
9036
0
    } else if (type->base == NULL) {
9037
0
  xmlSchemaPCustomErr(ctxt,
9038
0
      XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
9039
0
      NULL, node,
9040
0
      "Either the attribute 'itemType' or the <simpleType> child "
9041
0
      "must be present", NULL);
9042
0
    }
9043
0
    if (child != NULL) {
9044
0
  xmlSchemaPContentErr(ctxt,
9045
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
9046
0
      NULL, node, child, NULL, "(annotation?, simpleType?)");
9047
0
    }
9048
0
    if ((type->base == NULL) &&
9049
0
  (type->subtypes == NULL) &&
9050
0
  (xmlSchemaGetPropNode(node, "itemType") == NULL)) {
9051
0
  xmlSchemaPCustomErr(ctxt,
9052
0
      XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
9053
0
      NULL, node,
9054
0
      "Either the attribute 'itemType' or the <simpleType> child "
9055
0
      "must be present", NULL);
9056
0
    }
9057
0
    return (NULL);
9058
0
}
9059
9060
/**
9061
 * xmlSchemaParseSimpleType:
9062
 * @ctxt:  a schema validation context
9063
 * @schema:  the schema being built
9064
 * @node:  a subtree containing XML Schema information
9065
 *
9066
 * parse a XML schema Simple Type definition
9067
 * *WARNING* this interface is highly subject to change
9068
 *
9069
 * Returns -1 in case of error, 0 if the declaration is improper and
9070
 * 1 in case of success.
9071
 */
9072
static xmlSchemaTypePtr
9073
xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
9074
                         xmlNodePtr node, int topLevel)
9075
0
{
9076
0
    xmlSchemaTypePtr type, oldCtxtType;
9077
0
    xmlNodePtr child = NULL;
9078
0
    const xmlChar *attrValue = NULL;
9079
0
    xmlAttrPtr attr;
9080
0
    int hasRestriction = 0;
9081
9082
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
9083
0
        return (NULL);
9084
9085
0
    if (topLevel) {
9086
0
  attr = xmlSchemaGetPropNode(node, "name");
9087
0
  if (attr == NULL) {
9088
0
      xmlSchemaPMissingAttrErr(ctxt,
9089
0
    XML_SCHEMAP_S4S_ATTR_MISSING,
9090
0
    NULL, node,
9091
0
    "name", NULL);
9092
0
      return (NULL);
9093
0
  } else {
9094
0
      if (xmlSchemaPValAttrNode(ctxt,
9095
0
    NULL, attr,
9096
0
    xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &attrValue) != 0)
9097
0
    return (NULL);
9098
      /*
9099
      * Skip built-in types.
9100
      */
9101
0
      if (ctxt->isS4S) {
9102
0
    xmlSchemaTypePtr biType;
9103
9104
0
    if (ctxt->isRedefine) {
9105
        /*
9106
        * REDEFINE: Disallow redefinition of built-in-types.
9107
        * TODO: It seems that the spec does not say anything
9108
        * about this case.
9109
        */
9110
0
        xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE,
9111
0
      NULL, node,
9112
0
      "Redefinition of built-in simple types is not "
9113
0
      "supported", NULL);
9114
0
        return(NULL);
9115
0
    }
9116
0
    biType = xmlSchemaGetPredefinedType(attrValue, xmlSchemaNs);
9117
0
    if (biType != NULL)
9118
0
        return (biType);
9119
0
      }
9120
0
  }
9121
0
    }
9122
    /*
9123
    * TargetNamespace:
9124
    * SPEC "The `actual value` of the targetNamespace [attribute]
9125
    * of the <schema> ancestor element information item if present,
9126
    * otherwise `absent`.
9127
    */
9128
0
    if (topLevel == 0) {
9129
#ifdef ENABLE_NAMED_LOCALS
9130
        char buf[40];
9131
#endif
9132
  /*
9133
  * Parse as local simple type definition.
9134
  */
9135
#ifdef ENABLE_NAMED_LOCALS
9136
        snprintf(buf, 39, "#ST%d", ctxt->counter++ + 1);
9137
  type = xmlSchemaAddType(ctxt, schema,
9138
      XML_SCHEMA_TYPE_SIMPLE,
9139
      xmlDictLookup(ctxt->dict, (const xmlChar *)buf, -1),
9140
      ctxt->targetNamespace, node, 0);
9141
#else
9142
0
  type = xmlSchemaAddType(ctxt, schema,
9143
0
      XML_SCHEMA_TYPE_SIMPLE,
9144
0
      NULL, ctxt->targetNamespace, node, 0);
9145
0
#endif
9146
0
  if (type == NULL)
9147
0
      return (NULL);
9148
0
  type->type = XML_SCHEMA_TYPE_SIMPLE;
9149
0
  type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
9150
  /*
9151
  * Check for illegal attributes.
9152
  */
9153
0
  attr = node->properties;
9154
0
  while (attr != NULL) {
9155
0
      if (attr->ns == NULL) {
9156
0
    if (!xmlStrEqual(attr->name, BAD_CAST "id")) {
9157
0
        xmlSchemaPIllegalAttrErr(ctxt,
9158
0
      XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
9159
0
    }
9160
0
      } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
9161
0
        xmlSchemaPIllegalAttrErr(ctxt,
9162
0
      XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
9163
0
      }
9164
0
      attr = attr->next;
9165
0
  }
9166
0
    } else {
9167
  /*
9168
  * Parse as global simple type definition.
9169
  *
9170
  * Note that attrValue is the value of the attribute "name" here.
9171
  */
9172
0
  type = xmlSchemaAddType(ctxt, schema, XML_SCHEMA_TYPE_SIMPLE,
9173
0
      attrValue, ctxt->targetNamespace, node, 1);
9174
0
  if (type == NULL)
9175
0
      return (NULL);
9176
0
  type->type = XML_SCHEMA_TYPE_SIMPLE;
9177
0
  type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
9178
0
  type->flags |= XML_SCHEMAS_TYPE_GLOBAL;
9179
  /*
9180
  * Check for illegal attributes.
9181
  */
9182
0
  attr = node->properties;
9183
0
  while (attr != NULL) {
9184
0
      if (attr->ns == NULL) {
9185
0
    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
9186
0
        (!xmlStrEqual(attr->name, BAD_CAST "name")) &&
9187
0
        (!xmlStrEqual(attr->name, BAD_CAST "final"))) {
9188
0
        xmlSchemaPIllegalAttrErr(ctxt,
9189
0
      XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
9190
0
    }
9191
0
      } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
9192
0
    xmlSchemaPIllegalAttrErr(ctxt,
9193
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
9194
0
      }
9195
0
      attr = attr->next;
9196
0
  }
9197
  /*
9198
  * Attribute "final".
9199
  */
9200
0
  attr = xmlSchemaGetPropNode(node, "final");
9201
0
  if (attr == NULL) {
9202
0
      if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
9203
0
    type->flags |= XML_SCHEMAS_TYPE_FINAL_RESTRICTION;
9204
0
      if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_LIST)
9205
0
    type->flags |= XML_SCHEMAS_TYPE_FINAL_LIST;
9206
0
      if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_UNION)
9207
0
    type->flags |= XML_SCHEMAS_TYPE_FINAL_UNION;
9208
0
  } else {
9209
0
      attrValue = xmlSchemaGetProp(ctxt, node, "final");
9210
0
      if (xmlSchemaPValAttrBlockFinal(attrValue, &(type->flags),
9211
0
    -1, -1, XML_SCHEMAS_TYPE_FINAL_RESTRICTION, -1,
9212
0
    XML_SCHEMAS_TYPE_FINAL_LIST,
9213
0
    XML_SCHEMAS_TYPE_FINAL_UNION) != 0) {
9214
9215
0
    xmlSchemaPSimpleTypeErr(ctxt,
9216
0
        XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
9217
0
        WXS_BASIC_CAST type, (xmlNodePtr) attr,
9218
0
        NULL, "(#all | List of (list | union | restriction)",
9219
0
        attrValue, NULL, NULL, NULL);
9220
0
      }
9221
0
  }
9222
0
    }
9223
0
    type->targetNamespace = ctxt->targetNamespace;
9224
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
9225
    /*
9226
    * And now for the children...
9227
    */
9228
0
    oldCtxtType = ctxt->ctxtType;
9229
9230
0
    ctxt->ctxtType = type;
9231
9232
0
    child = node->children;
9233
0
    if (IS_SCHEMA(child, "annotation")) {
9234
0
        type->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
9235
0
        child = child->next;
9236
0
    }
9237
0
    if (child == NULL) {
9238
0
  xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_MISSING,
9239
0
      NULL, node, child, NULL,
9240
0
      "(annotation?, (restriction | list | union))");
9241
0
    } else if (IS_SCHEMA(child, "restriction")) {
9242
0
        xmlSchemaParseRestriction(ctxt, schema, child,
9243
0
      XML_SCHEMA_TYPE_SIMPLE);
9244
0
  hasRestriction = 1;
9245
0
        child = child->next;
9246
0
    } else if (IS_SCHEMA(child, "list")) {
9247
0
        xmlSchemaParseList(ctxt, schema, child);
9248
0
        child = child->next;
9249
0
    } else if (IS_SCHEMA(child, "union")) {
9250
0
        xmlSchemaParseUnion(ctxt, schema, child);
9251
0
        child = child->next;
9252
0
    }
9253
0
    if (child != NULL) {
9254
0
  xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
9255
0
      NULL, node, child, NULL,
9256
0
      "(annotation?, (restriction | list | union))");
9257
0
    }
9258
    /*
9259
    * REDEFINE: SPEC src-redefine (5)
9260
    * "Within the [children], each <simpleType> must have a
9261
    * <restriction> among its [children] ... the `actual value` of whose
9262
    * base [attribute] must be the same as the `actual value` of its own
9263
    * name attribute plus target namespace;"
9264
    */
9265
0
    if (topLevel && ctxt->isRedefine && (! hasRestriction)) {
9266
0
  xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE,
9267
0
      NULL, node, "This is a redefinition, thus the "
9268
0
      "<simpleType> must have a <restriction> child", NULL);
9269
0
    }
9270
9271
0
    ctxt->ctxtType = oldCtxtType;
9272
0
    return (type);
9273
0
}
9274
9275
/**
9276
 * xmlSchemaParseModelGroupDefRef:
9277
 * @ctxt:  the parser context
9278
 * @schema: the schema being built
9279
 * @node:  the node
9280
 *
9281
 * Parses a reference to a model group definition.
9282
 *
9283
 * We will return a particle component with a qname-component or
9284
 * NULL in case of an error.
9285
 */
9286
static xmlSchemaTreeItemPtr
9287
xmlSchemaParseModelGroupDefRef(xmlSchemaParserCtxtPtr ctxt,
9288
             xmlSchemaPtr schema,
9289
             xmlNodePtr node)
9290
0
{
9291
0
    xmlSchemaParticlePtr item;
9292
0
    xmlNodePtr child = NULL;
9293
0
    xmlAttrPtr attr;
9294
0
    const xmlChar *ref = NULL, *refNs = NULL;
9295
0
    int min, max;
9296
9297
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
9298
0
        return (NULL);
9299
9300
0
    attr = xmlSchemaGetPropNode(node, "ref");
9301
0
    if (attr == NULL) {
9302
0
  xmlSchemaPMissingAttrErr(ctxt,
9303
0
      XML_SCHEMAP_S4S_ATTR_MISSING,
9304
0
      NULL, node, "ref", NULL);
9305
0
  return (NULL);
9306
0
    } else if (xmlSchemaPValAttrNodeQName(ctxt, schema, NULL,
9307
0
  attr, &refNs, &ref) != 0) {
9308
0
  return (NULL);
9309
0
    }
9310
0
    xmlSchemaCheckReference(ctxt, schema, node, attr, refNs);
9311
0
    min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger");
9312
0
    max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1,
9313
0
  "(xs:nonNegativeInteger | unbounded)");
9314
    /*
9315
    * Check for illegal attributes.
9316
    */
9317
0
    attr = node->properties;
9318
0
    while (attr != NULL) {
9319
0
  if (attr->ns == NULL) {
9320
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "ref")) &&
9321
0
    (!xmlStrEqual(attr->name, BAD_CAST "id")) &&
9322
0
    (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) &&
9323
0
    (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs"))) {
9324
0
    xmlSchemaPIllegalAttrErr(ctxt,
9325
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
9326
0
      }
9327
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
9328
0
      xmlSchemaPIllegalAttrErr(ctxt,
9329
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
9330
0
  }
9331
0
  attr = attr->next;
9332
0
    }
9333
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
9334
0
    item = xmlSchemaAddParticle(ctxt, node, min, max);
9335
0
    if (item == NULL)
9336
0
  return (NULL);
9337
    /*
9338
    * Create a qname-reference and set as the term; it will be substituted
9339
    * for the model group after the reference has been resolved.
9340
    */
9341
0
    item->children = (xmlSchemaTreeItemPtr)
9342
0
  xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_GROUP, ref, refNs);
9343
0
    xmlSchemaPCheckParticleCorrect_2(ctxt, item, node, min, max);
9344
    /*
9345
    * And now for the children...
9346
    */
9347
0
    child = node->children;
9348
    /* TODO: Is annotation even allowed for a model group reference? */
9349
0
    if (IS_SCHEMA(child, "annotation")) {
9350
  /*
9351
  * TODO: What to do exactly with the annotation?
9352
  */
9353
0
  item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
9354
0
  child = child->next;
9355
0
    }
9356
0
    if (child != NULL) {
9357
0
  xmlSchemaPContentErr(ctxt,
9358
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
9359
0
      NULL, node, child, NULL,
9360
0
      "(annotation?)");
9361
0
    }
9362
    /*
9363
    * Corresponds to no component at all if minOccurs==maxOccurs==0.
9364
    */
9365
0
    if ((min == 0) && (max == 0))
9366
0
  return (NULL);
9367
9368
0
    return ((xmlSchemaTreeItemPtr) item);
9369
0
}
9370
9371
/**
9372
 * xmlSchemaParseModelGroupDefinition:
9373
 * @ctxt:  a schema validation context
9374
 * @schema:  the schema being built
9375
 * @node:  a subtree containing XML Schema information
9376
 *
9377
 * Parses a XML schema model group definition.
9378
 *
9379
 * Note that the constraint src-redefine (6.2) can't be applied until
9380
 * references have been resolved. So we will do this at the
9381
 * component fixup level.
9382
 *
9383
 * *WARNING* this interface is highly subject to change
9384
 *
9385
 * Returns -1 in case of error, 0 if the declaration is improper and
9386
 *         1 in case of success.
9387
 */
9388
static xmlSchemaModelGroupDefPtr
9389
xmlSchemaParseModelGroupDefinition(xmlSchemaParserCtxtPtr ctxt,
9390
           xmlSchemaPtr schema,
9391
           xmlNodePtr node)
9392
0
{
9393
0
    xmlSchemaModelGroupDefPtr item;
9394
0
    xmlNodePtr child = NULL;
9395
0
    xmlAttrPtr attr;
9396
0
    const xmlChar *name;
9397
9398
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
9399
0
        return (NULL);
9400
9401
0
    attr = xmlSchemaGetPropNode(node, "name");
9402
0
    if (attr == NULL) {
9403
0
  xmlSchemaPMissingAttrErr(ctxt,
9404
0
      XML_SCHEMAP_S4S_ATTR_MISSING,
9405
0
      NULL, node,
9406
0
      "name", NULL);
9407
0
  return (NULL);
9408
0
    } else if (xmlSchemaPValAttrNode(ctxt, NULL, attr,
9409
0
  xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
9410
0
  return (NULL);
9411
0
    }
9412
0
    item = xmlSchemaAddModelGroupDefinition(ctxt, schema, name,
9413
0
  ctxt->targetNamespace, node);
9414
0
    if (item == NULL)
9415
0
  return (NULL);
9416
    /*
9417
    * Check for illegal attributes.
9418
    */
9419
0
    attr = node->properties;
9420
0
    while (attr != NULL) {
9421
0
  if (attr->ns == NULL) {
9422
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "name")) &&
9423
0
    (!xmlStrEqual(attr->name, BAD_CAST "id"))) {
9424
0
    xmlSchemaPIllegalAttrErr(ctxt,
9425
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
9426
0
      }
9427
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
9428
0
      xmlSchemaPIllegalAttrErr(ctxt,
9429
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
9430
0
  }
9431
0
  attr = attr->next;
9432
0
    }
9433
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
9434
    /*
9435
    * And now for the children...
9436
    */
9437
0
    child = node->children;
9438
0
    if (IS_SCHEMA(child, "annotation")) {
9439
0
  item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
9440
0
  child = child->next;
9441
0
    }
9442
0
    if (IS_SCHEMA(child, "all")) {
9443
0
  item->children = xmlSchemaParseModelGroup(ctxt, schema, child,
9444
0
      XML_SCHEMA_TYPE_ALL, 0);
9445
0
  child = child->next;
9446
0
    } else if (IS_SCHEMA(child, "choice")) {
9447
0
  item->children = xmlSchemaParseModelGroup(ctxt, schema, child,
9448
0
      XML_SCHEMA_TYPE_CHOICE, 0);
9449
0
  child = child->next;
9450
0
    } else if (IS_SCHEMA(child, "sequence")) {
9451
0
  item->children = xmlSchemaParseModelGroup(ctxt, schema, child,
9452
0
      XML_SCHEMA_TYPE_SEQUENCE, 0);
9453
0
  child = child->next;
9454
0
    }
9455
9456
9457
9458
0
    if (child != NULL) {
9459
0
  xmlSchemaPContentErr(ctxt,
9460
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
9461
0
      NULL, node, child, NULL,
9462
0
      "(annotation?, (all | choice | sequence)?)");
9463
0
    }
9464
0
    return (item);
9465
0
}
9466
9467
/**
9468
 * xmlSchemaCleanupDoc:
9469
 * @ctxt:  a schema validation context
9470
 * @node:  the root of the document.
9471
 *
9472
 * removes unwanted nodes in a schemas document tree
9473
 */
9474
static void
9475
xmlSchemaCleanupDoc(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr root)
9476
0
{
9477
0
    xmlNodePtr delete, cur;
9478
9479
0
    if ((ctxt == NULL) || (root == NULL)) return;
9480
9481
    /*
9482
     * Remove all the blank text nodes
9483
     */
9484
0
    delete = NULL;
9485
0
    cur = root;
9486
0
    while (cur != NULL) {
9487
0
        if (delete != NULL) {
9488
0
            xmlUnlinkNode(delete);
9489
0
            xmlFreeNode(delete);
9490
0
            delete = NULL;
9491
0
        }
9492
0
        if (cur->type == XML_TEXT_NODE) {
9493
0
            if (IS_BLANK_NODE(cur)) {
9494
0
                if (xmlNodeGetSpacePreserve(cur) != 1) {
9495
0
                    delete = cur;
9496
0
                }
9497
0
            }
9498
0
        } else if ((cur->type != XML_ELEMENT_NODE) &&
9499
0
                   (cur->type != XML_CDATA_SECTION_NODE)) {
9500
0
            delete = cur;
9501
0
            goto skip_children;
9502
0
        }
9503
9504
        /*
9505
         * Skip to next node
9506
         */
9507
0
        if (cur->children != NULL) {
9508
0
            if ((cur->children->type != XML_ENTITY_DECL) &&
9509
0
                (cur->children->type != XML_ENTITY_REF_NODE) &&
9510
0
                (cur->children->type != XML_ENTITY_NODE)) {
9511
0
                cur = cur->children;
9512
0
                continue;
9513
0
            }
9514
0
        }
9515
0
      skip_children:
9516
0
        if (cur->next != NULL) {
9517
0
            cur = cur->next;
9518
0
            continue;
9519
0
        }
9520
9521
0
        do {
9522
0
            cur = cur->parent;
9523
0
            if (cur == NULL)
9524
0
                break;
9525
0
            if (cur == root) {
9526
0
                cur = NULL;
9527
0
                break;
9528
0
            }
9529
0
            if (cur->next != NULL) {
9530
0
                cur = cur->next;
9531
0
                break;
9532
0
            }
9533
0
        } while (cur != NULL);
9534
0
    }
9535
0
    if (delete != NULL) {
9536
0
        xmlUnlinkNode(delete);
9537
0
        xmlFreeNode(delete);
9538
0
        delete = NULL;
9539
0
    }
9540
0
}
9541
9542
9543
static void
9544
xmlSchemaClearSchemaDefaults(xmlSchemaPtr schema)
9545
0
{
9546
0
    if (schema->flags & XML_SCHEMAS_QUALIF_ELEM)
9547
0
  schema->flags ^= XML_SCHEMAS_QUALIF_ELEM;
9548
9549
0
    if (schema->flags & XML_SCHEMAS_QUALIF_ATTR)
9550
0
  schema->flags ^= XML_SCHEMAS_QUALIF_ATTR;
9551
9552
0
    if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION)
9553
0
  schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_EXTENSION;
9554
0
    if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
9555
0
  schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION;
9556
0
    if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_LIST)
9557
0
  schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_LIST;
9558
0
    if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_UNION)
9559
0
  schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_UNION;
9560
9561
0
    if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION)
9562
0
  schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION;
9563
0
    if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION)
9564
0
  schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION;
9565
0
    if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION)
9566
0
  schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION;
9567
0
}
9568
9569
static int
9570
xmlSchemaParseSchemaElement(xmlSchemaParserCtxtPtr ctxt,
9571
           xmlSchemaPtr schema,
9572
           xmlNodePtr node)
9573
0
{
9574
0
    xmlAttrPtr attr;
9575
0
    const xmlChar *val;
9576
0
    int res = 0, oldErrs = ctxt->nberrors;
9577
9578
    /*
9579
    * Those flags should be moved to the parser context flags,
9580
    * since they are not visible at the component level. I.e.
9581
    * they are used if processing schema *documents* only.
9582
    */
9583
0
    res = xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
9584
0
    HFAILURE;
9585
9586
    /*
9587
    * Since the version is of type xs:token, we won't bother to
9588
    * check it.
9589
    */
9590
    /* REMOVED:
9591
    attr = xmlSchemaGetPropNode(node, "version");
9592
    if (attr != NULL) {
9593
  res = xmlSchemaPValAttrNode(ctxt, NULL, NULL, attr,
9594
      xmlSchemaGetBuiltInType(XML_SCHEMAS_TOKEN), &val);
9595
  HFAILURE;
9596
    }
9597
    */
9598
0
    attr = xmlSchemaGetPropNode(node, "targetNamespace");
9599
0
    if (attr != NULL) {
9600
0
  res = xmlSchemaPValAttrNode(ctxt, NULL, attr,
9601
0
      xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), NULL);
9602
0
  HFAILURE;
9603
0
  if (res != 0) {
9604
0
      ctxt->stop = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
9605
0
      goto exit;
9606
0
  }
9607
0
    }
9608
0
    attr = xmlSchemaGetPropNode(node, "elementFormDefault");
9609
0
    if (attr != NULL) {
9610
0
  val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
9611
0
  res = xmlSchemaPValAttrFormDefault(val, &schema->flags,
9612
0
      XML_SCHEMAS_QUALIF_ELEM);
9613
0
  HFAILURE;
9614
0
  if (res != 0) {
9615
0
      xmlSchemaPSimpleTypeErr(ctxt,
9616
0
    XML_SCHEMAP_ELEMFORMDEFAULT_VALUE,
9617
0
    NULL, (xmlNodePtr) attr, NULL,
9618
0
    "(qualified | unqualified)", val, NULL, NULL, NULL);
9619
0
  }
9620
0
    }
9621
0
    attr = xmlSchemaGetPropNode(node, "attributeFormDefault");
9622
0
    if (attr != NULL) {
9623
0
  val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
9624
0
  res = xmlSchemaPValAttrFormDefault(val, &schema->flags,
9625
0
      XML_SCHEMAS_QUALIF_ATTR);
9626
0
  HFAILURE;
9627
0
  if (res != 0) {
9628
0
      xmlSchemaPSimpleTypeErr(ctxt,
9629
0
    XML_SCHEMAP_ATTRFORMDEFAULT_VALUE,
9630
0
    NULL, (xmlNodePtr) attr, NULL,
9631
0
    "(qualified | unqualified)", val, NULL, NULL, NULL);
9632
0
  }
9633
0
    }
9634
0
    attr = xmlSchemaGetPropNode(node, "finalDefault");
9635
0
    if (attr != NULL) {
9636
0
  val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
9637
0
  res = xmlSchemaPValAttrBlockFinal(val, &(schema->flags), -1,
9638
0
      XML_SCHEMAS_FINAL_DEFAULT_EXTENSION,
9639
0
      XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION,
9640
0
      -1,
9641
0
      XML_SCHEMAS_FINAL_DEFAULT_LIST,
9642
0
      XML_SCHEMAS_FINAL_DEFAULT_UNION);
9643
0
  HFAILURE;
9644
0
  if (res != 0) {
9645
0
      xmlSchemaPSimpleTypeErr(ctxt,
9646
0
    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
9647
0
    NULL, (xmlNodePtr) attr, NULL,
9648
0
    "(#all | List of (extension | restriction | list | union))",
9649
0
    val, NULL, NULL, NULL);
9650
0
  }
9651
0
    }
9652
0
    attr = xmlSchemaGetPropNode(node, "blockDefault");
9653
0
    if (attr != NULL) {
9654
0
  val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
9655
0
  res = xmlSchemaPValAttrBlockFinal(val, &(schema->flags), -1,
9656
0
      XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION,
9657
0
      XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION,
9658
0
      XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION, -1, -1);
9659
0
  HFAILURE;
9660
0
  if (res != 0) {
9661
0
      xmlSchemaPSimpleTypeErr(ctxt,
9662
0
    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
9663
0
    NULL, (xmlNodePtr) attr, NULL,
9664
0
    "(#all | List of (extension | restriction | substitution))",
9665
0
    val, NULL, NULL, NULL);
9666
0
  }
9667
0
    }
9668
9669
0
exit:
9670
0
    if (oldErrs != ctxt->nberrors)
9671
0
  res = ctxt->err;
9672
0
    return(res);
9673
0
exit_failure:
9674
0
    return(-1);
9675
0
}
9676
9677
/**
9678
 * xmlSchemaParseSchemaTopLevel:
9679
 * @ctxt:  a schema validation context
9680
 * @schema:  the schemas
9681
 * @nodes:  the list of top level nodes
9682
 *
9683
 * Returns the internal XML Schema structure built from the resource or
9684
 *         NULL in case of error
9685
 */
9686
static int
9687
xmlSchemaParseSchemaTopLevel(xmlSchemaParserCtxtPtr ctxt,
9688
                             xmlSchemaPtr schema, xmlNodePtr nodes)
9689
0
{
9690
0
    xmlNodePtr child;
9691
0
    xmlSchemaAnnotPtr annot;
9692
0
    int res = 0, oldErrs, tmpOldErrs;
9693
9694
0
    if ((ctxt == NULL) || (schema == NULL) || (nodes == NULL))
9695
0
        return(-1);
9696
9697
0
    oldErrs = ctxt->nberrors;
9698
0
    child = nodes;
9699
0
    while ((IS_SCHEMA(child, "include")) ||
9700
0
     (IS_SCHEMA(child, "import")) ||
9701
0
     (IS_SCHEMA(child, "redefine")) ||
9702
0
     (IS_SCHEMA(child, "annotation"))) {
9703
0
  if (IS_SCHEMA(child, "annotation")) {
9704
0
      annot = xmlSchemaParseAnnotation(ctxt, child, 1);
9705
0
      if (schema->annot == NULL)
9706
0
    schema->annot = annot;
9707
0
      else
9708
0
    xmlSchemaFreeAnnot(annot);
9709
0
  } else if (IS_SCHEMA(child, "import")) {
9710
0
      tmpOldErrs = ctxt->nberrors;
9711
0
      res = xmlSchemaParseImport(ctxt, schema, child);
9712
0
      HFAILURE;
9713
0
      HSTOP(ctxt);
9714
0
      if (tmpOldErrs != ctxt->nberrors)
9715
0
    goto exit;
9716
0
  } else if (IS_SCHEMA(child, "include")) {
9717
0
      tmpOldErrs = ctxt->nberrors;
9718
0
      res = xmlSchemaParseInclude(ctxt, schema, child);
9719
0
      HFAILURE;
9720
0
      HSTOP(ctxt);
9721
0
      if (tmpOldErrs != ctxt->nberrors)
9722
0
    goto exit;
9723
0
  } else if (IS_SCHEMA(child, "redefine")) {
9724
0
      tmpOldErrs = ctxt->nberrors;
9725
0
      res = xmlSchemaParseRedefine(ctxt, schema, child);
9726
0
      HFAILURE;
9727
0
      HSTOP(ctxt);
9728
0
      if (tmpOldErrs != ctxt->nberrors)
9729
0
    goto exit;
9730
0
  }
9731
0
  child = child->next;
9732
0
    }
9733
    /*
9734
    * URGENT TODO: Change the functions to return int results.
9735
    * We need especially to catch internal errors.
9736
    */
9737
0
    while (child != NULL) {
9738
0
  if (IS_SCHEMA(child, "complexType")) {
9739
0
      xmlSchemaParseComplexType(ctxt, schema, child, 1);
9740
0
      child = child->next;
9741
0
  } else if (IS_SCHEMA(child, "simpleType")) {
9742
0
      xmlSchemaParseSimpleType(ctxt, schema, child, 1);
9743
0
      child = child->next;
9744
0
  } else if (IS_SCHEMA(child, "element")) {
9745
0
      xmlSchemaParseElement(ctxt, schema, child, NULL, 1);
9746
0
      child = child->next;
9747
0
  } else if (IS_SCHEMA(child, "attribute")) {
9748
0
      xmlSchemaParseGlobalAttribute(ctxt, schema, child);
9749
0
      child = child->next;
9750
0
  } else if (IS_SCHEMA(child, "attributeGroup")) {
9751
0
      xmlSchemaParseAttributeGroupDefinition(ctxt, schema, child);
9752
0
      child = child->next;
9753
0
  } else if (IS_SCHEMA(child, "group")) {
9754
0
      xmlSchemaParseModelGroupDefinition(ctxt, schema, child);
9755
0
      child = child->next;
9756
0
  } else if (IS_SCHEMA(child, "notation")) {
9757
0
      xmlSchemaParseNotation(ctxt, schema, child);
9758
0
      child = child->next;
9759
0
  } else {
9760
0
      xmlSchemaPContentErr(ctxt,
9761
0
    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
9762
0
    NULL, child->parent, child,
9763
0
    NULL, "((include | import | redefine | annotation)*, "
9764
0
    "(((simpleType | complexType | group | attributeGroup) "
9765
0
    "| element | attribute | notation), annotation*)*)");
9766
0
      child = child->next;
9767
0
  }
9768
0
  while (IS_SCHEMA(child, "annotation")) {
9769
      /*
9770
      * TODO: We should add all annotations.
9771
      */
9772
0
      annot = xmlSchemaParseAnnotation(ctxt, child, 1);
9773
0
      if (schema->annot == NULL)
9774
0
    schema->annot = annot;
9775
0
      else
9776
0
    xmlSchemaFreeAnnot(annot);
9777
0
      child = child->next;
9778
0
  }
9779
0
    }
9780
0
exit:
9781
0
    ctxt->ctxtType = NULL;
9782
0
    if (oldErrs != ctxt->nberrors)
9783
0
  res = ctxt->err;
9784
0
    return(res);
9785
0
exit_failure:
9786
0
    return(-1);
9787
0
}
9788
9789
static xmlSchemaSchemaRelationPtr
9790
xmlSchemaSchemaRelationCreate(void)
9791
0
{
9792
0
    xmlSchemaSchemaRelationPtr ret;
9793
9794
0
    ret = (xmlSchemaSchemaRelationPtr)
9795
0
  xmlMalloc(sizeof(xmlSchemaSchemaRelation));
9796
0
    if (ret == NULL) {
9797
0
  xmlSchemaPErrMemory(NULL);
9798
0
  return(NULL);
9799
0
    }
9800
0
    memset(ret, 0, sizeof(xmlSchemaSchemaRelation));
9801
0
    return(ret);
9802
0
}
9803
9804
#if 0
9805
static void
9806
xmlSchemaSchemaRelationFree(xmlSchemaSchemaRelationPtr rel)
9807
{
9808
    xmlFree(rel);
9809
}
9810
#endif
9811
9812
static void
9813
xmlSchemaRedefListFree(xmlSchemaRedefPtr redef)
9814
0
{
9815
0
    xmlSchemaRedefPtr prev;
9816
9817
0
    while (redef != NULL) {
9818
0
  prev = redef;
9819
0
  redef = redef->next;
9820
0
  xmlFree(prev);
9821
0
    }
9822
0
}
9823
9824
static void
9825
xmlSchemaConstructionCtxtFree(xmlSchemaConstructionCtxtPtr con)
9826
0
{
9827
    /*
9828
    * After the construction context has been freed, there will be
9829
    * no schema graph available any more. Only the schema buckets
9830
    * will stay alive, which are put into the "schemasImports" and
9831
    * "includes" slots of the xmlSchema.
9832
    */
9833
0
    if (con->buckets != NULL)
9834
0
  xmlSchemaItemListFree(con->buckets);
9835
0
    if (con->pending != NULL)
9836
0
  xmlSchemaItemListFree(con->pending);
9837
0
    if (con->substGroups != NULL)
9838
0
  xmlHashFree(con->substGroups, xmlSchemaSubstGroupFreeEntry);
9839
0
    if (con->redefs != NULL)
9840
0
  xmlSchemaRedefListFree(con->redefs);
9841
0
    if (con->dict != NULL)
9842
0
  xmlDictFree(con->dict);
9843
0
    xmlFree(con);
9844
0
}
9845
9846
static xmlSchemaConstructionCtxtPtr
9847
xmlSchemaConstructionCtxtCreate(xmlDictPtr dict)
9848
0
{
9849
0
    xmlSchemaConstructionCtxtPtr ret;
9850
9851
0
    ret = (xmlSchemaConstructionCtxtPtr)
9852
0
  xmlMalloc(sizeof(xmlSchemaConstructionCtxt));
9853
0
    if (ret == NULL) {
9854
0
        xmlSchemaPErrMemory(NULL);
9855
0
        return (NULL);
9856
0
    }
9857
0
    memset(ret, 0, sizeof(xmlSchemaConstructionCtxt));
9858
9859
0
    ret->buckets = xmlSchemaItemListCreate();
9860
0
    if (ret->buckets == NULL) {
9861
0
  xmlSchemaPErrMemory(NULL);
9862
0
  xmlFree(ret);
9863
0
        return (NULL);
9864
0
    }
9865
0
    ret->pending = xmlSchemaItemListCreate();
9866
0
    if (ret->pending == NULL) {
9867
0
  xmlSchemaPErrMemory(NULL);
9868
0
  xmlSchemaConstructionCtxtFree(ret);
9869
0
        return (NULL);
9870
0
    }
9871
0
    ret->dict = dict;
9872
0
    xmlDictReference(dict);
9873
0
    return(ret);
9874
0
}
9875
9876
static xmlSchemaParserCtxtPtr
9877
xmlSchemaParserCtxtCreate(void)
9878
0
{
9879
0
    xmlSchemaParserCtxtPtr ret;
9880
9881
0
    ret = (xmlSchemaParserCtxtPtr) xmlMalloc(sizeof(xmlSchemaParserCtxt));
9882
0
    if (ret == NULL) {
9883
0
        xmlSchemaPErrMemory(NULL);
9884
0
        return (NULL);
9885
0
    }
9886
0
    memset(ret, 0, sizeof(xmlSchemaParserCtxt));
9887
0
    ret->type = XML_SCHEMA_CTXT_PARSER;
9888
0
    ret->attrProhibs = xmlSchemaItemListCreate();
9889
0
    if (ret->attrProhibs == NULL) {
9890
0
  xmlFree(ret);
9891
0
  return(NULL);
9892
0
    }
9893
0
    return(ret);
9894
0
}
9895
9896
/**
9897
 * xmlSchemaNewParserCtxtUseDict:
9898
 * @URL:  the location of the schema
9899
 * @dict: the dictionary to be used
9900
 *
9901
 * Create an XML Schemas parse context for that file/resource expected
9902
 * to contain an XML Schemas file.
9903
 *
9904
 * Returns the parser context or NULL in case of error
9905
 */
9906
static xmlSchemaParserCtxtPtr
9907
xmlSchemaNewParserCtxtUseDict(const char *URL, xmlDictPtr dict)
9908
0
{
9909
0
    xmlSchemaParserCtxtPtr ret;
9910
9911
0
    ret = xmlSchemaParserCtxtCreate();
9912
0
    if (ret == NULL)
9913
0
        return (NULL);
9914
0
    ret->dict = dict;
9915
0
    xmlDictReference(dict);
9916
0
    if (URL != NULL)
9917
0
  ret->URL = xmlDictLookup(dict, (const xmlChar *) URL, -1);
9918
0
    return (ret);
9919
0
}
9920
9921
static int
9922
xmlSchemaCreatePCtxtOnVCtxt(xmlSchemaValidCtxtPtr vctxt)
9923
0
{
9924
0
    if (vctxt->pctxt == NULL) {
9925
0
        if (vctxt->schema != NULL)
9926
0
      vctxt->pctxt =
9927
0
    xmlSchemaNewParserCtxtUseDict("*", vctxt->schema->dict);
9928
0
  else
9929
0
      vctxt->pctxt = xmlSchemaNewParserCtxt("*");
9930
0
  if (vctxt->pctxt == NULL) {
9931
0
      VERROR_INT("xmlSchemaCreatePCtxtOnVCtxt",
9932
0
    "failed to create a temp. parser context");
9933
0
      return (-1);
9934
0
  }
9935
  /* TODO: Pass user data. */
9936
0
  xmlSchemaSetParserErrors(vctxt->pctxt, vctxt->error,
9937
0
      vctxt->warning, vctxt->errCtxt);
9938
0
  xmlSchemaSetParserStructuredErrors(vctxt->pctxt, vctxt->serror,
9939
0
      vctxt->errCtxt);
9940
0
    }
9941
0
    return (0);
9942
0
}
9943
9944
/**
9945
 * xmlSchemaGetSchemaBucket:
9946
 * @pctxt: the schema parser context
9947
 * @schemaLocation: the URI of the schema document
9948
 *
9949
 * Returns a schema bucket if it was already parsed.
9950
 *
9951
 * Returns a schema bucket if it was already parsed from
9952
 *         @schemaLocation, NULL otherwise.
9953
 */
9954
static xmlSchemaBucketPtr
9955
xmlSchemaGetSchemaBucket(xmlSchemaParserCtxtPtr pctxt,
9956
          const xmlChar *schemaLocation)
9957
0
{
9958
0
    xmlSchemaBucketPtr cur;
9959
0
    xmlSchemaItemListPtr list;
9960
9961
0
    list = pctxt->constructor->buckets;
9962
0
    if (list->nbItems == 0)
9963
0
  return(NULL);
9964
0
    else {
9965
0
  int i;
9966
0
  for (i = 0; i < list->nbItems; i++) {
9967
0
      cur = (xmlSchemaBucketPtr) list->items[i];
9968
      /* Pointer comparison! */
9969
0
      if (cur->schemaLocation == schemaLocation)
9970
0
    return(cur);
9971
0
  }
9972
0
    }
9973
0
    return(NULL);
9974
0
}
9975
9976
static xmlSchemaBucketPtr
9977
xmlSchemaGetChameleonSchemaBucket(xmlSchemaParserCtxtPtr pctxt,
9978
             const xmlChar *schemaLocation,
9979
             const xmlChar *targetNamespace)
9980
0
{
9981
0
    xmlSchemaBucketPtr cur;
9982
0
    xmlSchemaItemListPtr list;
9983
9984
0
    list = pctxt->constructor->buckets;
9985
0
    if (list->nbItems == 0)
9986
0
  return(NULL);
9987
0
    else {
9988
0
  int i;
9989
0
  for (i = 0; i < list->nbItems; i++) {
9990
0
      cur = (xmlSchemaBucketPtr) list->items[i];
9991
      /* Pointer comparison! */
9992
0
      if ((cur->origTargetNamespace == NULL) &&
9993
0
    (cur->schemaLocation == schemaLocation) &&
9994
0
    (cur->targetNamespace == targetNamespace))
9995
0
    return(cur);
9996
0
  }
9997
0
    }
9998
0
    return(NULL);
9999
0
}
10000
10001
10002
#define IS_BAD_SCHEMA_DOC(b) \
10003
0
    (((b)->doc == NULL) && ((b)->schemaLocation != NULL))
10004
10005
static xmlSchemaBucketPtr
10006
xmlSchemaGetSchemaBucketByTNS(xmlSchemaParserCtxtPtr pctxt,
10007
         const xmlChar *targetNamespace,
10008
         int imported)
10009
0
{
10010
0
    xmlSchemaBucketPtr cur;
10011
0
    xmlSchemaItemListPtr list;
10012
10013
0
    list = pctxt->constructor->buckets;
10014
0
    if (list->nbItems == 0)
10015
0
  return(NULL);
10016
0
    else {
10017
0
  int i;
10018
0
  for (i = 0; i < list->nbItems; i++) {
10019
0
      cur = (xmlSchemaBucketPtr) list->items[i];
10020
0
      if ((! IS_BAD_SCHEMA_DOC(cur)) &&
10021
0
    (cur->origTargetNamespace == targetNamespace) &&
10022
0
    ((imported && cur->imported) ||
10023
0
     ((!imported) && (!cur->imported))))
10024
0
    return(cur);
10025
0
  }
10026
0
    }
10027
0
    return(NULL);
10028
0
}
10029
10030
static int
10031
xmlSchemaParseNewDocWithContext(xmlSchemaParserCtxtPtr pctxt,
10032
         xmlSchemaPtr schema,
10033
         xmlSchemaBucketPtr bucket)
10034
0
{
10035
0
    int oldFlags;
10036
0
    xmlDocPtr oldDoc;
10037
0
    xmlNodePtr node;
10038
0
    int ret, oldErrs;
10039
0
    xmlSchemaBucketPtr oldbucket = pctxt->constructor->bucket;
10040
10041
    /*
10042
    * Save old values; reset the *main* schema.
10043
    * URGENT TODO: This is not good; move the per-document information
10044
    * to the parser. Get rid of passing the main schema to the
10045
    * parsing functions.
10046
    */
10047
0
    oldFlags = schema->flags;
10048
0
    oldDoc = schema->doc;
10049
0
    if (schema->flags != 0)
10050
0
  xmlSchemaClearSchemaDefaults(schema);
10051
0
    schema->doc = bucket->doc;
10052
0
    pctxt->schema = schema;
10053
    /*
10054
    * Keep the current target namespace on the parser *not* on the
10055
    * main schema.
10056
    */
10057
0
    pctxt->targetNamespace = bucket->targetNamespace;
10058
0
    WXS_CONSTRUCTOR(pctxt)->bucket = bucket;
10059
10060
0
    if ((bucket->targetNamespace != NULL) &&
10061
0
  xmlStrEqual(bucket->targetNamespace, xmlSchemaNs)) {
10062
  /*
10063
  * We are parsing the schema for schemas!
10064
  */
10065
0
  pctxt->isS4S = 1;
10066
0
    }
10067
    /* Mark it as parsed, even if parsing fails. */
10068
0
    bucket->parsed++;
10069
    /* Compile the schema doc. */
10070
0
    node = xmlDocGetRootElement(bucket->doc);
10071
0
    ret = xmlSchemaParseSchemaElement(pctxt, schema, node);
10072
0
    if (ret != 0)
10073
0
  goto exit;
10074
    /* An empty schema; just get out. */
10075
0
    if (node->children == NULL)
10076
0
  goto exit;
10077
0
    oldErrs = pctxt->nberrors;
10078
0
    ret = xmlSchemaParseSchemaTopLevel(pctxt, schema, node->children);
10079
0
    if (ret != 0)
10080
0
  goto exit;
10081
    /*
10082
    * TODO: Not nice, but I'm not 100% sure we will get always an error
10083
    * as a result of the above functions; so better rely on pctxt->err
10084
    * as well.
10085
    */
10086
0
    if ((ret == 0) && (oldErrs != pctxt->nberrors)) {
10087
0
  ret = pctxt->err;
10088
0
  goto exit;
10089
0
    }
10090
10091
0
exit:
10092
0
    WXS_CONSTRUCTOR(pctxt)->bucket = oldbucket;
10093
    /* Restore schema values. */
10094
0
    schema->doc = oldDoc;
10095
0
    schema->flags = oldFlags;
10096
0
    return(ret);
10097
0
}
10098
10099
static int
10100
xmlSchemaParseNewDoc(xmlSchemaParserCtxtPtr pctxt,
10101
         xmlSchemaPtr schema,
10102
         xmlSchemaBucketPtr bucket)
10103
0
{
10104
0
    xmlSchemaParserCtxtPtr newpctxt;
10105
0
    int res = 0;
10106
10107
0
    if (bucket == NULL)
10108
0
  return(0);
10109
0
    if (bucket->parsed) {
10110
0
  PERROR_INT("xmlSchemaParseNewDoc",
10111
0
      "reparsing a schema doc");
10112
0
  return(-1);
10113
0
    }
10114
0
    if (bucket->doc == NULL) {
10115
0
  PERROR_INT("xmlSchemaParseNewDoc",
10116
0
      "parsing a schema doc, but there's no doc");
10117
0
  return(-1);
10118
0
    }
10119
0
    if (pctxt->constructor == NULL) {
10120
0
  PERROR_INT("xmlSchemaParseNewDoc",
10121
0
      "no constructor");
10122
0
  return(-1);
10123
0
    }
10124
    /* Create and init the temporary parser context. */
10125
0
    newpctxt = xmlSchemaNewParserCtxtUseDict(
10126
0
  (const char *) bucket->schemaLocation, pctxt->dict);
10127
0
    if (newpctxt == NULL)
10128
0
  return(-1);
10129
0
    newpctxt->constructor = pctxt->constructor;
10130
    /*
10131
    * TODO: Can we avoid that the parser knows about the main schema?
10132
    * It would be better if he knows about the current schema bucket
10133
    * only.
10134
    */
10135
0
    newpctxt->schema = schema;
10136
0
    xmlSchemaSetParserErrors(newpctxt, pctxt->error, pctxt->warning,
10137
0
  pctxt->errCtxt);
10138
0
    xmlSchemaSetParserStructuredErrors(newpctxt, pctxt->serror,
10139
0
  pctxt->errCtxt);
10140
0
    newpctxt->counter = pctxt->counter;
10141
10142
10143
0
    res = xmlSchemaParseNewDocWithContext(newpctxt, schema, bucket);
10144
10145
    /* Channel back errors and cleanup the temporary parser context. */
10146
0
    if (res != 0)
10147
0
  pctxt->err = res;
10148
0
    pctxt->nberrors += newpctxt->nberrors;
10149
0
    pctxt->counter = newpctxt->counter;
10150
0
    newpctxt->constructor = NULL;
10151
    /* Free the parser context. */
10152
0
    xmlSchemaFreeParserCtxt(newpctxt);
10153
0
    return(res);
10154
0
}
10155
10156
static void
10157
xmlSchemaSchemaRelationAddChild(xmlSchemaBucketPtr bucket,
10158
        xmlSchemaSchemaRelationPtr rel)
10159
0
{
10160
0
    xmlSchemaSchemaRelationPtr cur = bucket->relations;
10161
10162
0
    if (cur == NULL) {
10163
0
  bucket->relations = rel;
10164
0
  return;
10165
0
    }
10166
0
    while (cur->next != NULL)
10167
0
  cur = cur->next;
10168
0
    cur->next = rel;
10169
0
}
10170
10171
10172
static const xmlChar *
10173
xmlSchemaBuildAbsoluteURI(xmlDictPtr dict, const xmlChar* location,
10174
        xmlNodePtr ctxtNode)
10175
0
{
10176
    /*
10177
    * Build an absolute location URI.
10178
    */
10179
0
    if (location != NULL) {
10180
0
  if (ctxtNode == NULL)
10181
0
      return(location);
10182
0
  else {
10183
0
      xmlChar *base, *URI;
10184
0
      const xmlChar *ret = NULL;
10185
10186
0
      base = xmlNodeGetBase(ctxtNode->doc, ctxtNode);
10187
0
      if (base == NULL) {
10188
0
    URI = xmlBuildURI(location, ctxtNode->doc->URL);
10189
0
      } else {
10190
0
    URI = xmlBuildURI(location, base);
10191
0
    xmlFree(base);
10192
0
      }
10193
0
      if (URI != NULL) {
10194
0
    ret = xmlDictLookup(dict, URI, -1);
10195
0
    xmlFree(URI);
10196
0
    return(ret);
10197
0
      }
10198
0
  }
10199
0
    }
10200
0
    return(NULL);
10201
0
}
10202
10203
10204
10205
/**
10206
 * xmlSchemaAddSchemaDoc:
10207
 * @pctxt:  a schema validation context
10208
 * @schema:  the schema being built
10209
 * @node:  a subtree containing XML Schema information
10210
 *
10211
 * Parse an included (and to-be-redefined) XML schema document.
10212
 *
10213
 * Returns 0 on success, a positive error code on errors and
10214
 *         -1 in case of an internal or API error.
10215
 */
10216
10217
static int
10218
xmlSchemaAddSchemaDoc(xmlSchemaParserCtxtPtr pctxt,
10219
    int type, /* import or include or redefine */
10220
    const xmlChar *schemaLocation,
10221
    xmlDocPtr schemaDoc,
10222
    const char *schemaBuffer,
10223
    int schemaBufferLen,
10224
    xmlNodePtr invokingNode,
10225
    const xmlChar *sourceTargetNamespace,
10226
    const xmlChar *importNamespace,
10227
    xmlSchemaBucketPtr *bucket)
10228
0
{
10229
0
    const xmlChar *targetNamespace = NULL;
10230
0
    xmlSchemaSchemaRelationPtr relation = NULL;
10231
0
    xmlDocPtr doc = NULL;
10232
0
    int res = 0, err = 0, located = 0, preserveDoc = 0;
10233
0
    xmlSchemaBucketPtr bkt = NULL;
10234
10235
0
    if (bucket != NULL)
10236
0
  *bucket = NULL;
10237
10238
0
    switch (type) {
10239
0
  case XML_SCHEMA_SCHEMA_IMPORT:
10240
0
  case XML_SCHEMA_SCHEMA_MAIN:
10241
0
      err = XML_SCHEMAP_SRC_IMPORT;
10242
0
      break;
10243
0
  case XML_SCHEMA_SCHEMA_INCLUDE:
10244
0
      err = XML_SCHEMAP_SRC_INCLUDE;
10245
0
      break;
10246
0
  case XML_SCHEMA_SCHEMA_REDEFINE:
10247
0
      err = XML_SCHEMAP_SRC_REDEFINE;
10248
0
      break;
10249
0
    }
10250
10251
10252
    /* Special handling for the main schema:
10253
    * skip the location and relation logic and just parse the doc.
10254
    * We need just a bucket to be returned in this case.
10255
    */
10256
0
    if ((type == XML_SCHEMA_SCHEMA_MAIN) || (! WXS_HAS_BUCKETS(pctxt)))
10257
0
  goto doc_load;
10258
10259
    /* Note that we expect the location to be an absolute URI. */
10260
0
    if (schemaLocation != NULL) {
10261
0
  bkt = xmlSchemaGetSchemaBucket(pctxt, schemaLocation);
10262
0
  if ((bkt != NULL) &&
10263
0
      (pctxt->constructor->bucket == bkt)) {
10264
      /* Report self-imports/inclusions/redefinitions. */
10265
10266
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt, err,
10267
0
    invokingNode, NULL,
10268
0
    "The schema must not import/include/redefine itself",
10269
0
    NULL, NULL);
10270
0
      goto exit;
10271
0
  }
10272
0
    }
10273
    /*
10274
    * Create a relation for the graph of schemas.
10275
    */
10276
0
    relation = xmlSchemaSchemaRelationCreate();
10277
0
    if (relation == NULL)
10278
0
  return(-1);
10279
0
    xmlSchemaSchemaRelationAddChild(pctxt->constructor->bucket,
10280
0
  relation);
10281
0
    relation->type = type;
10282
10283
    /*
10284
    * Save the namespace import information.
10285
    */
10286
0
    if (WXS_IS_BUCKET_IMPMAIN(type)) {
10287
0
  relation->importNamespace = importNamespace;
10288
0
  if (schemaLocation == NULL) {
10289
      /*
10290
      * No location; this is just an import of the namespace.
10291
      * Note that we don't assign a bucket to the relation
10292
      * in this case.
10293
      */
10294
0
      goto exit;
10295
0
  }
10296
0
  targetNamespace = importNamespace;
10297
0
    }
10298
10299
    /* Did we already fetch the doc? */
10300
0
    if (bkt != NULL) {
10301
0
  if ((WXS_IS_BUCKET_IMPMAIN(type)) && (! bkt->imported)) {
10302
      /*
10303
      * We included/redefined and then try to import a schema,
10304
      * but the new location provided for import was different.
10305
      */
10306
0
      if (schemaLocation == NULL)
10307
0
    schemaLocation = BAD_CAST "in_memory_buffer";
10308
0
      if (!xmlStrEqual(schemaLocation,
10309
0
    bkt->schemaLocation)) {
10310
0
    xmlSchemaCustomErr(ACTXT_CAST pctxt, err,
10311
0
        invokingNode, NULL,
10312
0
        "The schema document '%s' cannot be imported, since "
10313
0
        "it was already included or redefined",
10314
0
        schemaLocation, NULL);
10315
0
    goto exit;
10316
0
      }
10317
0
  } else if ((! WXS_IS_BUCKET_IMPMAIN(type)) && (bkt->imported)) {
10318
      /*
10319
      * We imported and then try to include/redefine a schema,
10320
      * but the new location provided for the include/redefine
10321
      * was different.
10322
      */
10323
0
      if (schemaLocation == NULL)
10324
0
    schemaLocation = BAD_CAST "in_memory_buffer";
10325
0
      if (!xmlStrEqual(schemaLocation,
10326
0
    bkt->schemaLocation)) {
10327
0
    xmlSchemaCustomErr(ACTXT_CAST pctxt, err,
10328
0
        invokingNode, NULL,
10329
0
        "The schema document '%s' cannot be included or "
10330
0
        "redefined, since it was already imported",
10331
0
        schemaLocation, NULL);
10332
0
    goto exit;
10333
0
      }
10334
0
  }
10335
0
    }
10336
10337
0
    if (WXS_IS_BUCKET_IMPMAIN(type)) {
10338
  /*
10339
  * Given that the schemaLocation [attribute] is only a hint, it is open
10340
  * to applications to ignore all but the first <import> for a given
10341
  * namespace, regardless of the `actual value` of schemaLocation, but
10342
  * such a strategy risks missing useful information when new
10343
  * schemaLocations are offered.
10344
  *
10345
  * We will use the first <import> that comes with a location.
10346
  * Further <import>s *with* a location, will result in an error.
10347
  * TODO: Better would be to just report a warning here, but
10348
  * we'll try it this way until someone complains.
10349
  *
10350
  * Schema Document Location Strategy:
10351
  * 3 Based on the namespace name, identify an existing schema document,
10352
  * either as a resource which is an XML document or a <schema> element
10353
  * information item, in some local schema repository;
10354
  * 5 Attempt to resolve the namespace name to locate such a resource.
10355
  *
10356
  * NOTE: (3) and (5) are not supported.
10357
  */
10358
0
  if (bkt != NULL) {
10359
0
      relation->bucket = bkt;
10360
0
      goto exit;
10361
0
  }
10362
0
  bkt = xmlSchemaGetSchemaBucketByTNS(pctxt,
10363
0
      importNamespace, 1);
10364
10365
0
  if (bkt != NULL) {
10366
0
      relation->bucket = bkt;
10367
0
      if (bkt->schemaLocation == NULL) {
10368
    /* First given location of the schema; load the doc. */
10369
0
    bkt->schemaLocation = schemaLocation;
10370
0
      } else {
10371
0
    if (!xmlStrEqual(schemaLocation,
10372
0
        bkt->schemaLocation)) {
10373
        /*
10374
        * Additional location given; just skip it.
10375
        * URGENT TODO: We should report a warning here.
10376
        * res = XML_SCHEMAP_SRC_IMPORT;
10377
        */
10378
0
        if (schemaLocation == NULL)
10379
0
      schemaLocation = BAD_CAST "in_memory_buffer";
10380
10381
0
        xmlSchemaCustomWarning(ACTXT_CAST pctxt,
10382
0
      XML_SCHEMAP_WARN_SKIP_SCHEMA,
10383
0
      invokingNode, NULL,
10384
0
      "Skipping import of schema located at '%s' for the "
10385
0
      "namespace '%s', since this namespace was already "
10386
0
      "imported with the schema located at '%s'",
10387
0
      schemaLocation, importNamespace, bkt->schemaLocation);
10388
0
    }
10389
0
    goto exit;
10390
0
      }
10391
0
  }
10392
  /*
10393
  * No bucket + first location: load the doc and create a
10394
  * bucket.
10395
  */
10396
0
    } else {
10397
  /* <include> and <redefine> */
10398
0
  if (bkt != NULL) {
10399
10400
0
      if ((bkt->origTargetNamespace == NULL) &&
10401
0
    (bkt->targetNamespace != sourceTargetNamespace)) {
10402
0
    xmlSchemaBucketPtr chamel;
10403
10404
    /*
10405
    * Chameleon include/redefine: skip loading only if it was
10406
    * already build for the targetNamespace of the including
10407
    * schema.
10408
    */
10409
    /*
10410
    * URGENT TODO: If the schema is a chameleon-include then copy
10411
    * the components into the including schema and modify the
10412
    * targetNamespace of those components, do nothing otherwise.
10413
    * NOTE: This is currently worked-around by compiling the
10414
    * chameleon for every distinct including targetNamespace; thus
10415
    * not performant at the moment.
10416
    * TODO: Check when the namespace in wildcards for chameleons
10417
    * needs to be converted: before we built wildcard intersections
10418
    * or after.
10419
    *   Answer: after!
10420
    */
10421
0
    chamel = xmlSchemaGetChameleonSchemaBucket(pctxt,
10422
0
        schemaLocation, sourceTargetNamespace);
10423
0
    if (chamel != NULL) {
10424
        /* A fitting chameleon was already parsed; NOP. */
10425
0
        relation->bucket = chamel;
10426
0
        goto exit;
10427
0
    }
10428
    /*
10429
    * We need to parse the chameleon again for a different
10430
    * targetNamespace.
10431
    * CHAMELEON TODO: Optimize this by only parsing the
10432
    * chameleon once, and then copying the components to
10433
    * the new targetNamespace.
10434
    */
10435
0
    bkt = NULL;
10436
0
      } else {
10437
0
    relation->bucket = bkt;
10438
0
    goto exit;
10439
0
      }
10440
0
  }
10441
0
    }
10442
0
    if ((bkt != NULL) && (bkt->doc != NULL)) {
10443
0
  PERROR_INT("xmlSchemaAddSchemaDoc",
10444
0
      "trying to load a schema doc, but a doc is already "
10445
0
      "assigned to the schema bucket");
10446
0
  goto exit_failure;
10447
0
    }
10448
10449
0
doc_load:
10450
    /*
10451
    * Load the document.
10452
    */
10453
0
    if (schemaDoc != NULL) {
10454
0
  doc = schemaDoc;
10455
  /* Don' free this one, since it was provided by the caller. */
10456
0
  preserveDoc = 1;
10457
  /* TODO: Does the context or the doc hold the location? */
10458
0
  if (schemaDoc->URL != NULL)
10459
0
      schemaLocation = xmlDictLookup(pctxt->dict,
10460
0
    schemaDoc->URL, -1);
10461
0
        else
10462
0
      schemaLocation = BAD_CAST "in_memory_buffer";
10463
0
    } else if ((schemaLocation != NULL) || (schemaBuffer != NULL)) {
10464
0
  xmlParserCtxtPtr parserCtxt;
10465
10466
0
  parserCtxt = xmlNewParserCtxt();
10467
0
  if (parserCtxt == NULL) {
10468
0
      xmlSchemaPErrMemory(NULL);
10469
0
      goto exit_failure;
10470
0
  }
10471
10472
0
        if (pctxt->serror != NULL)
10473
0
            xmlCtxtSetErrorHandler(parserCtxt, pctxt->serror, pctxt->errCtxt);
10474
0
        if (pctxt->resourceLoader != NULL)
10475
0
            xmlCtxtSetResourceLoader(parserCtxt, pctxt->resourceLoader,
10476
0
                                     pctxt->resourceCtxt);
10477
10478
0
  if ((pctxt->dict != NULL) && (parserCtxt->dict != NULL)) {
10479
      /*
10480
      * TODO: Do we have to burden the schema parser dict with all
10481
      * the content of the schema doc?
10482
      */
10483
0
      xmlDictFree(parserCtxt->dict);
10484
0
      parserCtxt->dict = pctxt->dict;
10485
0
      xmlDictReference(parserCtxt->dict);
10486
0
  }
10487
0
  if (schemaLocation != NULL) {
10488
      /* Parse from file. */
10489
0
      doc = xmlCtxtReadFile(parserCtxt, (const char *) schemaLocation,
10490
0
    NULL, SCHEMAS_PARSE_OPTIONS);
10491
0
  } else if (schemaBuffer != NULL) {
10492
      /* Parse from memory buffer. */
10493
0
      doc = xmlCtxtReadMemory(parserCtxt, schemaBuffer, schemaBufferLen,
10494
0
    NULL, NULL, SCHEMAS_PARSE_OPTIONS);
10495
0
      schemaLocation = BAD_CAST "in_memory_buffer";
10496
0
      if (doc != NULL)
10497
0
    doc->URL = xmlStrdup(schemaLocation);
10498
0
  }
10499
  /*
10500
  * For <import>:
10501
  * 2.1 The referent is (a fragment of) a resource which is an
10502
  * XML document (see clause 1.1), which in turn corresponds to
10503
  * a <schema> element information item in a well-formed information
10504
  * set, which in turn corresponds to a valid schema.
10505
  * TODO: (2.1) fragments of XML documents are not supported.
10506
  *
10507
  * 2.2 The referent is a <schema> element information item in
10508
  * a well-formed information set, which in turn corresponds
10509
  * to a valid schema.
10510
  * TODO: (2.2) is not supported.
10511
  */
10512
0
  if (doc == NULL) {
10513
0
      const xmlError *lerr;
10514
0
      lerr = xmlGetLastError();
10515
      /*
10516
      * Check if this a parser error, or if the document could
10517
      * just not be located.
10518
      * TODO: Try to find specific error codes to react only on
10519
      * localisation failures.
10520
      */
10521
0
      if ((lerr == NULL) || (lerr->domain != XML_FROM_IO)) {
10522
    /*
10523
    * We assume a parser error here.
10524
    */
10525
0
    located = 1;
10526
    /* TODO: Error code ?? */
10527
0
    res = XML_SCHEMAP_SRC_IMPORT_2_1;
10528
0
    xmlSchemaCustomErr(ACTXT_CAST pctxt, res,
10529
0
        invokingNode, NULL,
10530
0
        "Failed to parse the XML resource '%s'",
10531
0
        schemaLocation, NULL);
10532
0
      }
10533
0
  }
10534
0
  xmlFreeParserCtxt(parserCtxt);
10535
0
  if ((doc == NULL) && located)
10536
0
      goto exit_error;
10537
0
    } else {
10538
0
  xmlSchemaPErr(pctxt, NULL,
10539
0
      XML_SCHEMAP_NOTHING_TO_PARSE,
10540
0
      "No information for parsing was provided with the "
10541
0
      "given schema parser context.\n",
10542
0
      NULL, NULL);
10543
0
  goto exit_failure;
10544
0
    }
10545
    /*
10546
    * Preprocess the document.
10547
    */
10548
0
    if (doc != NULL) {
10549
0
  xmlNodePtr docElem = NULL;
10550
10551
0
  located = 1;
10552
0
  docElem = xmlDocGetRootElement(doc);
10553
0
  if (docElem == NULL) {
10554
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt, XML_SCHEMAP_NOROOT,
10555
0
    invokingNode, NULL,
10556
0
    "The document '%s' has no document element",
10557
0
    schemaLocation, NULL);
10558
0
      goto exit_error;
10559
0
  }
10560
  /*
10561
  * Remove all the blank text nodes.
10562
  */
10563
0
  xmlSchemaCleanupDoc(pctxt, docElem);
10564
  /*
10565
  * Check the schema's top level element.
10566
  */
10567
0
  if (!IS_SCHEMA(docElem, "schema")) {
10568
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt, XML_SCHEMAP_NOT_SCHEMA,
10569
0
    invokingNode, NULL,
10570
0
    "The XML document '%s' is not a schema document",
10571
0
    schemaLocation, NULL);
10572
0
      goto exit_error;
10573
0
  }
10574
  /*
10575
  * Note that we don't apply a type check for the
10576
  * targetNamespace value here.
10577
  */
10578
0
  targetNamespace = xmlSchemaGetProp(pctxt, docElem,
10579
0
      "targetNamespace");
10580
0
    }
10581
10582
/* after_doc_loading: */
10583
0
    if ((bkt == NULL) && located) {
10584
  /* Only create a bucket if the schema was located. */
10585
0
        bkt = xmlSchemaBucketCreate(pctxt, type,
10586
0
      targetNamespace);
10587
0
  if (bkt == NULL)
10588
0
      goto exit_failure;
10589
0
    }
10590
0
    if (bkt != NULL) {
10591
0
  bkt->schemaLocation = schemaLocation;
10592
0
  bkt->located = located;
10593
0
  if (doc != NULL) {
10594
0
      bkt->doc = doc;
10595
0
      bkt->targetNamespace = targetNamespace;
10596
0
      bkt->origTargetNamespace = targetNamespace;
10597
0
      if (preserveDoc)
10598
0
    bkt->preserveDoc = 1;
10599
0
  }
10600
0
  if (WXS_IS_BUCKET_IMPMAIN(type))
10601
0
      bkt->imported++;
10602
      /*
10603
      * Add it to the graph of schemas.
10604
      */
10605
0
  if (relation != NULL)
10606
0
      relation->bucket = bkt;
10607
0
    }
10608
10609
0
exit:
10610
    /*
10611
    * Return the bucket explicitly; this is needed for the
10612
    * main schema.
10613
    */
10614
0
    if (bucket != NULL)
10615
0
  *bucket = bkt;
10616
0
    return (0);
10617
10618
0
exit_error:
10619
0
    if ((doc != NULL) && (! preserveDoc)) {
10620
0
  xmlFreeDoc(doc);
10621
0
  if (bkt != NULL)
10622
0
      bkt->doc = NULL;
10623
0
    }
10624
0
    return(pctxt->err);
10625
10626
0
exit_failure:
10627
0
    if ((doc != NULL) && (! preserveDoc)) {
10628
0
  xmlFreeDoc(doc);
10629
0
  if (bkt != NULL)
10630
0
      bkt->doc = NULL;
10631
0
    }
10632
0
    return (-1);
10633
0
}
10634
10635
/**
10636
 * xmlSchemaParseImport:
10637
 * @ctxt:  a schema validation context
10638
 * @schema:  the schema being built
10639
 * @node:  a subtree containing XML Schema information
10640
 *
10641
 * parse a XML schema Import definition
10642
 * *WARNING* this interface is highly subject to change
10643
 *
10644
 * Returns 0 in case of success, a positive error code if
10645
 * not valid and -1 in case of an internal error.
10646
 */
10647
static int
10648
xmlSchemaParseImport(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema,
10649
                     xmlNodePtr node)
10650
0
{
10651
0
    xmlNodePtr child;
10652
0
    const xmlChar *namespaceName = NULL, *schemaLocation = NULL;
10653
0
    const xmlChar *thisTargetNamespace;
10654
0
    xmlAttrPtr attr;
10655
0
    int ret = 0;
10656
0
    xmlSchemaBucketPtr bucket = NULL;
10657
10658
0
    if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
10659
0
        return (-1);
10660
10661
    /*
10662
    * Check for illegal attributes.
10663
    */
10664
0
    attr = node->properties;
10665
0
    while (attr != NULL) {
10666
0
  if (attr->ns == NULL) {
10667
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
10668
0
    (!xmlStrEqual(attr->name, BAD_CAST "namespace")) &&
10669
0
    (!xmlStrEqual(attr->name, BAD_CAST "schemaLocation"))) {
10670
0
    xmlSchemaPIllegalAttrErr(pctxt,
10671
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
10672
0
      }
10673
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
10674
0
      xmlSchemaPIllegalAttrErr(pctxt,
10675
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
10676
0
  }
10677
0
  attr = attr->next;
10678
0
    }
10679
    /*
10680
    * Extract and validate attributes.
10681
    */
10682
0
    if (xmlSchemaPValAttr(pctxt, NULL, node,
10683
0
  "namespace", xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
10684
0
  &namespaceName) != 0) {
10685
0
  xmlSchemaPSimpleTypeErr(pctxt,
10686
0
      XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
10687
0
      NULL, node,
10688
0
      xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
10689
0
      NULL, namespaceName, NULL, NULL, NULL);
10690
0
  return (pctxt->err);
10691
0
    }
10692
10693
0
    if (xmlSchemaPValAttr(pctxt, NULL, node,
10694
0
  "schemaLocation", xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
10695
0
  &schemaLocation) != 0) {
10696
0
  xmlSchemaPSimpleTypeErr(pctxt,
10697
0
      XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
10698
0
      NULL, node,
10699
0
      xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
10700
0
      NULL, schemaLocation, NULL, NULL, NULL);
10701
0
  return (pctxt->err);
10702
0
    }
10703
    /*
10704
    * And now for the children...
10705
    */
10706
0
    child = node->children;
10707
0
    if (IS_SCHEMA(child, "annotation")) {
10708
        /*
10709
         * the annotation here is simply discarded ...
10710
   * TODO: really?
10711
         */
10712
0
        child = child->next;
10713
0
    }
10714
0
    if (child != NULL) {
10715
0
  xmlSchemaPContentErr(pctxt,
10716
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
10717
0
      NULL, node, child, NULL,
10718
0
      "(annotation?)");
10719
0
    }
10720
    /*
10721
    * Apply additional constraints.
10722
    *
10723
    * Note that it is important to use the original @targetNamespace
10724
    * (or none at all), to rule out imports of schemas _with_ a
10725
    * @targetNamespace if the importing schema is a chameleon schema
10726
    * (with no @targetNamespace).
10727
    */
10728
0
    thisTargetNamespace = WXS_BUCKET(pctxt)->origTargetNamespace;
10729
0
    if (namespaceName != NULL) {
10730
  /*
10731
  * 1.1 If the namespace [attribute] is present, then its `actual value`
10732
  * must not match the `actual value` of the enclosing <schema>'s
10733
  * targetNamespace [attribute].
10734
  */
10735
0
  if (xmlStrEqual(thisTargetNamespace, namespaceName)) {
10736
0
      xmlSchemaPCustomErr(pctxt,
10737
0
    XML_SCHEMAP_SRC_IMPORT_1_1,
10738
0
    NULL, node,
10739
0
    "The value of the attribute 'namespace' must not match "
10740
0
    "the target namespace '%s' of the importing schema",
10741
0
    thisTargetNamespace);
10742
0
      return (pctxt->err);
10743
0
  }
10744
0
    } else {
10745
  /*
10746
  * 1.2 If the namespace [attribute] is not present, then the enclosing
10747
  * <schema> must have a targetNamespace [attribute].
10748
  */
10749
0
  if (thisTargetNamespace == NULL) {
10750
0
      xmlSchemaPCustomErr(pctxt,
10751
0
    XML_SCHEMAP_SRC_IMPORT_1_2,
10752
0
    NULL, node,
10753
0
    "The attribute 'namespace' must be existent if "
10754
0
    "the importing schema has no target namespace",
10755
0
    NULL);
10756
0
      return (pctxt->err);
10757
0
  }
10758
0
    }
10759
    /*
10760
    * Locate and acquire the schema document.
10761
    */
10762
0
    if (schemaLocation != NULL)
10763
0
  schemaLocation = xmlSchemaBuildAbsoluteURI(pctxt->dict,
10764
0
      schemaLocation, node);
10765
0
    ret = xmlSchemaAddSchemaDoc(pctxt, XML_SCHEMA_SCHEMA_IMPORT,
10766
0
  schemaLocation, NULL, NULL, 0, node, thisTargetNamespace,
10767
0
  namespaceName, &bucket);
10768
10769
0
    if (ret != 0)
10770
0
  return(ret);
10771
10772
    /*
10773
    * For <import>: "It is *not* an error for the application
10774
    * schema reference strategy to fail."
10775
    * So just don't parse if no schema document was found.
10776
    * Note that we will get no bucket if the schema could not be
10777
    * located or if there was no schemaLocation.
10778
    */
10779
0
    if ((bucket == NULL) && (schemaLocation != NULL)) {
10780
0
  xmlSchemaCustomWarning(ACTXT_CAST pctxt,
10781
0
      XML_SCHEMAP_WARN_UNLOCATED_SCHEMA,
10782
0
      node, NULL,
10783
0
      "Failed to locate a schema at location '%s'. "
10784
0
      "Skipping the import", schemaLocation, NULL, NULL);
10785
0
    }
10786
10787
0
    if ((bucket != NULL) && CAN_PARSE_SCHEMA(bucket)) {
10788
0
  ret = xmlSchemaParseNewDoc(pctxt, schema, bucket);
10789
0
    }
10790
10791
0
    return (ret);
10792
0
}
10793
10794
static int
10795
xmlSchemaParseIncludeOrRedefineAttrs(xmlSchemaParserCtxtPtr pctxt,
10796
             xmlSchemaPtr schema,
10797
             xmlNodePtr node,
10798
             xmlChar **schemaLocation,
10799
             int type)
10800
0
{
10801
0
    xmlAttrPtr attr;
10802
10803
0
    if ((pctxt == NULL) || (schema == NULL) || (node == NULL) ||
10804
0
  (schemaLocation == NULL))
10805
0
        return (-1);
10806
10807
0
    *schemaLocation = NULL;
10808
    /*
10809
    * Check for illegal attributes.
10810
    * Applies for both <include> and <redefine>.
10811
    */
10812
0
    attr = node->properties;
10813
0
    while (attr != NULL) {
10814
0
  if (attr->ns == NULL) {
10815
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
10816
0
    (!xmlStrEqual(attr->name, BAD_CAST "schemaLocation"))) {
10817
0
    xmlSchemaPIllegalAttrErr(pctxt,
10818
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
10819
0
      }
10820
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
10821
0
      xmlSchemaPIllegalAttrErr(pctxt,
10822
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
10823
0
  }
10824
0
  attr = attr->next;
10825
0
    }
10826
0
    xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
10827
    /*
10828
    * Preliminary step, extract the URI-Reference and make an URI
10829
    * from the base.
10830
    */
10831
    /*
10832
    * Attribute "schemaLocation" is mandatory.
10833
    */
10834
0
    attr = xmlSchemaGetPropNode(node, "schemaLocation");
10835
0
    if (attr != NULL) {
10836
0
        xmlChar *base = NULL;
10837
0
        xmlChar *uri = NULL;
10838
10839
0
  if (xmlSchemaPValAttrNode(pctxt, NULL, attr,
10840
0
      xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
10841
0
      (const xmlChar **) schemaLocation) != 0)
10842
0
      goto exit_error;
10843
0
  base = xmlNodeGetBase(node->doc, node);
10844
0
  if (base == NULL) {
10845
0
      uri = xmlBuildURI(*schemaLocation, node->doc->URL);
10846
0
  } else {
10847
0
      uri = xmlBuildURI(*schemaLocation, base);
10848
0
      xmlFree(base);
10849
0
  }
10850
0
  if (uri == NULL) {
10851
0
      PERROR_INT("xmlSchemaParseIncludeOrRedefine",
10852
0
    "could not build an URI from the schemaLocation")
10853
0
      goto exit_failure;
10854
0
  }
10855
0
  (*schemaLocation) = (xmlChar *) xmlDictLookup(pctxt->dict, uri, -1);
10856
0
  xmlFree(uri);
10857
0
    } else {
10858
0
  xmlSchemaPMissingAttrErr(pctxt,
10859
0
      XML_SCHEMAP_S4S_ATTR_MISSING,
10860
0
      NULL, node, "schemaLocation", NULL);
10861
0
  goto exit_error;
10862
0
    }
10863
    /*
10864
    * Report self-inclusion and self-redefinition.
10865
    */
10866
0
    if (xmlStrEqual(*schemaLocation, pctxt->URL)) {
10867
0
  if (type == XML_SCHEMA_SCHEMA_REDEFINE) {
10868
0
      xmlSchemaPCustomErr(pctxt,
10869
0
    XML_SCHEMAP_SRC_REDEFINE,
10870
0
    NULL, node,
10871
0
    "The schema document '%s' cannot redefine itself.",
10872
0
    *schemaLocation);
10873
0
  } else {
10874
0
      xmlSchemaPCustomErr(pctxt,
10875
0
    XML_SCHEMAP_SRC_INCLUDE,
10876
0
    NULL, node,
10877
0
    "The schema document '%s' cannot include itself.",
10878
0
    *schemaLocation);
10879
0
  }
10880
0
  goto exit_error;
10881
0
    }
10882
10883
0
    return(0);
10884
0
exit_error:
10885
0
    return(pctxt->err);
10886
0
exit_failure:
10887
0
    return(-1);
10888
0
}
10889
10890
static int
10891
xmlSchemaParseIncludeOrRedefine(xmlSchemaParserCtxtPtr pctxt,
10892
        xmlSchemaPtr schema,
10893
        xmlNodePtr node,
10894
        int type)
10895
0
{
10896
0
    xmlNodePtr child = NULL;
10897
0
    const xmlChar *schemaLocation = NULL;
10898
0
    int res = 0; /* hasRedefinitions = 0 */
10899
0
    int isChameleon = 0, wasChameleon = 0;
10900
0
    xmlSchemaBucketPtr bucket = NULL;
10901
10902
0
    if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
10903
0
        return (-1);
10904
10905
    /*
10906
    * Parse attributes. Note that the returned schemaLocation will
10907
    * be already converted to an absolute URI.
10908
    */
10909
0
    res = xmlSchemaParseIncludeOrRedefineAttrs(pctxt, schema,
10910
0
  node, (xmlChar **) (&schemaLocation), type);
10911
0
    if (res != 0)
10912
0
  return(res);
10913
    /*
10914
    * Load and add the schema document.
10915
    */
10916
0
    res = xmlSchemaAddSchemaDoc(pctxt, type, schemaLocation, NULL,
10917
0
  NULL, 0, node, pctxt->targetNamespace, NULL, &bucket);
10918
0
    if (res != 0)
10919
0
  return(res);
10920
    /*
10921
    * If we get no schema bucket back, then this means that the schema
10922
    * document could not be located or was broken XML or was not
10923
    * a schema document.
10924
    */
10925
0
    if ((bucket == NULL) || (bucket->doc == NULL)) {
10926
0
  if (type == XML_SCHEMA_SCHEMA_INCLUDE) {
10927
      /*
10928
      * WARNING for <include>:
10929
      * We will raise an error if the schema cannot be located
10930
      * for inclusions, since the that was the feedback from the
10931
      * schema people. I.e. the following spec piece will *not* be
10932
      * satisfied:
10933
      * SPEC src-include: "It is not an error for the `actual value` of the
10934
      * schemaLocation [attribute] to fail to resolve it all, in which
10935
      * case no corresponding inclusion is performed.
10936
      * So do we need a warning report here?"
10937
      */
10938
0
      res = XML_SCHEMAP_SRC_INCLUDE;
10939
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt, res,
10940
0
    node, NULL,
10941
0
    "Failed to load the document '%s' for inclusion",
10942
0
    schemaLocation, NULL);
10943
0
  } else {
10944
      /*
10945
      * NOTE: This was changed to raise an error even if no redefinitions
10946
      * are specified.
10947
      *
10948
      * SPEC src-redefine (1)
10949
      * "If there are any element information items among the [children]
10950
      * other than <annotation> then the `actual value` of the
10951
      * schemaLocation [attribute] must successfully resolve."
10952
      * TODO: Ask the WG if a the location has always to resolve
10953
      * here as well!
10954
      */
10955
0
      res = XML_SCHEMAP_SRC_REDEFINE;
10956
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt, res,
10957
0
    node, NULL,
10958
0
    "Failed to load the document '%s' for redefinition",
10959
0
    schemaLocation, NULL);
10960
0
  }
10961
0
    } else {
10962
  /*
10963
  * Check targetNamespace sanity before parsing the new schema.
10964
  * TODO: Note that we won't check further content if the
10965
  * targetNamespace was bad.
10966
  */
10967
0
  if (bucket->origTargetNamespace != NULL) {
10968
      /*
10969
      * SPEC src-include (2.1)
10970
      * "SII has a targetNamespace [attribute], and its `actual
10971
      * value` is identical to the `actual value` of the targetNamespace
10972
      * [attribute] of SII' (which must have such an [attribute])."
10973
      */
10974
0
      if (pctxt->targetNamespace == NULL) {
10975
0
    xmlSchemaCustomErr(ACTXT_CAST pctxt,
10976
0
        XML_SCHEMAP_SRC_INCLUDE,
10977
0
        node, NULL,
10978
0
        "The target namespace of the included/redefined schema "
10979
0
        "'%s' has to be absent, since the including/redefining "
10980
0
        "schema has no target namespace",
10981
0
        schemaLocation, NULL);
10982
0
    goto exit_error;
10983
0
      } else if (!xmlStrEqual(bucket->origTargetNamespace,
10984
0
    pctxt->targetNamespace)) {
10985
    /* TODO: Change error function. */
10986
0
    xmlSchemaPCustomErrExt(pctxt,
10987
0
        XML_SCHEMAP_SRC_INCLUDE,
10988
0
        NULL, node,
10989
0
        "The target namespace '%s' of the included/redefined "
10990
0
        "schema '%s' differs from '%s' of the "
10991
0
        "including/redefining schema",
10992
0
        bucket->origTargetNamespace, schemaLocation,
10993
0
        pctxt->targetNamespace);
10994
0
    goto exit_error;
10995
0
      }
10996
0
  } else if (pctxt->targetNamespace != NULL) {
10997
      /*
10998
      * Chameleons: the original target namespace will
10999
      * differ from the resulting namespace.
11000
      */
11001
0
      isChameleon = 1;
11002
0
      bucket->targetNamespace = pctxt->targetNamespace;
11003
0
  }
11004
0
    }
11005
    /*
11006
    * Parse the schema.
11007
    */
11008
0
    if (bucket && (!bucket->parsed) && (bucket->doc != NULL)) {
11009
0
  if (isChameleon) {
11010
      /* TODO: Get rid of this flag on the schema itself. */
11011
0
      if ((schema->flags & XML_SCHEMAS_INCLUDING_CONVERT_NS) == 0) {
11012
0
    schema->flags |= XML_SCHEMAS_INCLUDING_CONVERT_NS;
11013
0
      } else
11014
0
    wasChameleon = 1;
11015
0
  }
11016
0
  xmlSchemaParseNewDoc(pctxt, schema, bucket);
11017
  /* Restore chameleon flag. */
11018
0
  if (isChameleon && (!wasChameleon))
11019
0
      schema->flags ^= XML_SCHEMAS_INCLUDING_CONVERT_NS;
11020
0
    }
11021
    /*
11022
    * And now for the children...
11023
    */
11024
0
    child = node->children;
11025
0
    if (type == XML_SCHEMA_SCHEMA_REDEFINE) {
11026
  /*
11027
  * Parse (simpleType | complexType | group | attributeGroup))*
11028
  */
11029
0
  pctxt->redefined = bucket;
11030
  /*
11031
  * How to proceed if the redefined schema was not located?
11032
  */
11033
0
  pctxt->isRedefine = 1;
11034
0
  while (IS_SCHEMA(child, "annotation") ||
11035
0
      IS_SCHEMA(child, "simpleType") ||
11036
0
      IS_SCHEMA(child, "complexType") ||
11037
0
      IS_SCHEMA(child, "group") ||
11038
0
      IS_SCHEMA(child, "attributeGroup")) {
11039
0
      if (IS_SCHEMA(child, "annotation")) {
11040
    /*
11041
    * TODO: discard or not?
11042
    */
11043
0
      } else if (IS_SCHEMA(child, "simpleType")) {
11044
0
    xmlSchemaParseSimpleType(pctxt, schema, child, 1);
11045
0
      } else if (IS_SCHEMA(child, "complexType")) {
11046
0
    xmlSchemaParseComplexType(pctxt, schema, child, 1);
11047
    /* hasRedefinitions = 1; */
11048
0
      } else if (IS_SCHEMA(child, "group")) {
11049
    /* hasRedefinitions = 1; */
11050
0
    xmlSchemaParseModelGroupDefinition(pctxt,
11051
0
        schema, child);
11052
0
      } else if (IS_SCHEMA(child, "attributeGroup")) {
11053
    /* hasRedefinitions = 1; */
11054
0
    xmlSchemaParseAttributeGroupDefinition(pctxt, schema,
11055
0
        child);
11056
0
      }
11057
0
      child = child->next;
11058
0
  }
11059
0
  pctxt->redefined = NULL;
11060
0
  pctxt->isRedefine = 0;
11061
0
    } else {
11062
0
  if (IS_SCHEMA(child, "annotation")) {
11063
      /*
11064
      * TODO: discard or not?
11065
      */
11066
0
      child = child->next;
11067
0
  }
11068
0
    }
11069
0
    if (child != NULL) {
11070
0
  res = XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED;
11071
0
  if (type == XML_SCHEMA_SCHEMA_REDEFINE) {
11072
0
      xmlSchemaPContentErr(pctxt, res,
11073
0
    NULL, node, child, NULL,
11074
0
    "(annotation | (simpleType | complexType | group | attributeGroup))*");
11075
0
  } else {
11076
0
       xmlSchemaPContentErr(pctxt, res,
11077
0
    NULL, node, child, NULL,
11078
0
    "(annotation?)");
11079
0
  }
11080
0
    }
11081
0
    return(res);
11082
11083
0
exit_error:
11084
0
    return(pctxt->err);
11085
0
}
11086
11087
static int
11088
xmlSchemaParseRedefine(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema,
11089
                       xmlNodePtr node)
11090
0
{
11091
0
    int res;
11092
#ifndef ENABLE_REDEFINE
11093
    TODO
11094
    return(0);
11095
#endif
11096
0
    res = xmlSchemaParseIncludeOrRedefine(pctxt, schema, node,
11097
0
  XML_SCHEMA_SCHEMA_REDEFINE);
11098
0
    if (res != 0)
11099
0
  return(res);
11100
0
    return(0);
11101
0
}
11102
11103
static int
11104
xmlSchemaParseInclude(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema,
11105
                       xmlNodePtr node)
11106
0
{
11107
0
    int res;
11108
11109
0
    res = xmlSchemaParseIncludeOrRedefine(pctxt, schema, node,
11110
0
  XML_SCHEMA_SCHEMA_INCLUDE);
11111
0
    if (res != 0)
11112
0
  return(res);
11113
0
    return(0);
11114
0
}
11115
11116
/**
11117
 * xmlSchemaParseModelGroup:
11118
 * @ctxt:  a schema validation context
11119
 * @schema:  the schema being built
11120
 * @node:  a subtree containing XML Schema information
11121
 * @type: the "compositor" type
11122
 * @particleNeeded: if a a model group with a particle
11123
 *
11124
 * parse a XML schema Sequence definition.
11125
 * Applies parts of:
11126
 *   Schema Representation Constraint:
11127
 *     Redefinition Constraints and Semantics (src-redefine)
11128
 *     (6.1), (6.1.1), (6.1.2)
11129
 *
11130
 *   Schema Component Constraint:
11131
 *     All Group Limited (cos-all-limited) (2)
11132
 *     TODO: Actually this should go to component-level checks,
11133
 *     but is done here due to performance. Move it to an other layer
11134
 *     is schema construction via an API is implemented.
11135
 *
11136
 * *WARNING* this interface is highly subject to change
11137
 *
11138
 * Returns -1 in case of error, 0 if the declaration is improper and
11139
 *         1 in case of success.
11140
 */
11141
static xmlSchemaTreeItemPtr
11142
xmlSchemaParseModelGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
11143
       xmlNodePtr node, xmlSchemaTypeType type,
11144
       int withParticle)
11145
0
{
11146
0
    xmlSchemaModelGroupPtr item;
11147
0
    xmlSchemaParticlePtr particle = NULL;
11148
0
    xmlNodePtr child = NULL;
11149
0
    xmlAttrPtr attr;
11150
0
    int min = 1, max = 1, isElemRef, hasRefs = 0;
11151
11152
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
11153
0
        return (NULL);
11154
    /*
11155
    * Create a model group with the given compositor.
11156
    */
11157
0
    item = xmlSchemaAddModelGroup(ctxt, schema, type, node);
11158
0
    if (item == NULL)
11159
0
  return (NULL);
11160
11161
0
    if (withParticle) {
11162
0
  if (type == XML_SCHEMA_TYPE_ALL) {
11163
0
      min = xmlGetMinOccurs(ctxt, node, 0, 1, 1, "(0 | 1)");
11164
0
      max = xmlGetMaxOccurs(ctxt, node, 1, 1, 1, "1");
11165
0
  } else {
11166
      /* choice + sequence */
11167
0
      min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger");
11168
0
      max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1,
11169
0
    "(xs:nonNegativeInteger | unbounded)");
11170
0
  }
11171
0
  xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max);
11172
  /*
11173
  * Create a particle
11174
  */
11175
0
  particle = xmlSchemaAddParticle(ctxt, node, min, max);
11176
0
  if (particle == NULL)
11177
0
      return (NULL);
11178
0
  particle->children = (xmlSchemaTreeItemPtr) item;
11179
  /*
11180
  * Check for illegal attributes.
11181
  */
11182
0
  attr = node->properties;
11183
0
  while (attr != NULL) {
11184
0
      if (attr->ns == NULL) {
11185
0
    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
11186
0
        (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) &&
11187
0
        (!xmlStrEqual(attr->name, BAD_CAST "minOccurs"))) {
11188
0
        xmlSchemaPIllegalAttrErr(ctxt,
11189
0
      XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11190
0
    }
11191
0
      } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
11192
0
    xmlSchemaPIllegalAttrErr(ctxt,
11193
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11194
0
      }
11195
0
      attr = attr->next;
11196
0
  }
11197
0
    } else {
11198
  /*
11199
  * Check for illegal attributes.
11200
  */
11201
0
  attr = node->properties;
11202
0
  while (attr != NULL) {
11203
0
      if (attr->ns == NULL) {
11204
0
    if (!xmlStrEqual(attr->name, BAD_CAST "id")) {
11205
0
        xmlSchemaPIllegalAttrErr(ctxt,
11206
0
      XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11207
0
    }
11208
0
      } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
11209
0
    xmlSchemaPIllegalAttrErr(ctxt,
11210
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11211
0
      }
11212
0
      attr = attr->next;
11213
0
  }
11214
0
    }
11215
11216
    /*
11217
    * Extract and validate attributes.
11218
    */
11219
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
11220
    /*
11221
    * And now for the children...
11222
    */
11223
0
    child = node->children;
11224
0
    if (IS_SCHEMA(child, "annotation")) {
11225
0
        item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
11226
0
        child = child->next;
11227
0
    }
11228
0
    if (type == XML_SCHEMA_TYPE_ALL) {
11229
0
  xmlSchemaParticlePtr part, last = NULL;
11230
11231
0
  while (IS_SCHEMA(child, "element")) {
11232
0
      part = (xmlSchemaParticlePtr) xmlSchemaParseElement(ctxt,
11233
0
    schema, child, &isElemRef, 0);
11234
      /*
11235
      * SPEC cos-all-limited (2)
11236
      * "The {max occurs} of all the particles in the {particles}
11237
      * of the ('all') group must be 0 or 1.
11238
      */
11239
0
      if (part != NULL) {
11240
0
    if (isElemRef)
11241
0
        hasRefs++;
11242
0
    if (part->minOccurs > 1) {
11243
0
        xmlSchemaPCustomErr(ctxt,
11244
0
      XML_SCHEMAP_COS_ALL_LIMITED,
11245
0
      NULL, child,
11246
0
      "Invalid value for minOccurs (must be 0 or 1)",
11247
0
      NULL);
11248
        /* Reset to 1. */
11249
0
        part->minOccurs = 1;
11250
0
    }
11251
0
    if (part->maxOccurs > 1) {
11252
0
        xmlSchemaPCustomErr(ctxt,
11253
0
      XML_SCHEMAP_COS_ALL_LIMITED,
11254
0
      NULL, child,
11255
0
      "Invalid value for maxOccurs (must be 0 or 1)",
11256
0
      NULL);
11257
        /* Reset to 1. */
11258
0
        part->maxOccurs = 1;
11259
0
    }
11260
0
    if (last == NULL)
11261
0
        item->children = (xmlSchemaTreeItemPtr) part;
11262
0
    else
11263
0
        last->next = (xmlSchemaTreeItemPtr) part;
11264
0
    last = part;
11265
0
      }
11266
0
      child = child->next;
11267
0
  }
11268
0
  if (child != NULL) {
11269
0
      xmlSchemaPContentErr(ctxt,
11270
0
    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11271
0
    NULL, node, child, NULL,
11272
0
    "(annotation?, (annotation?, element*)");
11273
0
  }
11274
0
    } else {
11275
  /* choice + sequence */
11276
0
  xmlSchemaTreeItemPtr part = NULL, last = NULL;
11277
11278
0
  while ((IS_SCHEMA(child, "element")) ||
11279
0
      (IS_SCHEMA(child, "group")) ||
11280
0
      (IS_SCHEMA(child, "any")) ||
11281
0
      (IS_SCHEMA(child, "choice")) ||
11282
0
      (IS_SCHEMA(child, "sequence"))) {
11283
11284
0
      if (IS_SCHEMA(child, "element")) {
11285
0
    part = (xmlSchemaTreeItemPtr)
11286
0
        xmlSchemaParseElement(ctxt, schema, child, &isElemRef, 0);
11287
0
    if (part && isElemRef)
11288
0
        hasRefs++;
11289
0
      } else if (IS_SCHEMA(child, "group")) {
11290
0
    part =
11291
0
        xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
11292
0
    if (part != NULL)
11293
0
        hasRefs++;
11294
    /*
11295
    * Handle redefinitions.
11296
    */
11297
0
    if (ctxt->isRedefine && ctxt->redef &&
11298
0
        (ctxt->redef->item->type == XML_SCHEMA_TYPE_GROUP) &&
11299
0
        part && part->children)
11300
0
    {
11301
0
        if ((xmlSchemaGetQNameRefName(part->children) ==
11302
0
          ctxt->redef->refName) &&
11303
0
      (xmlSchemaGetQNameRefTargetNs(part->children) ==
11304
0
          ctxt->redef->refTargetNs))
11305
0
        {
11306
      /*
11307
      * SPEC src-redefine:
11308
      * (6.1) "If it has a <group> among its contents at
11309
      * some level the `actual value` of whose ref
11310
      * [attribute] is the same as the `actual value` of
11311
      * its own name attribute plus target namespace, then
11312
      * all of the following must be true:"
11313
      * (6.1.1) "It must have exactly one such group."
11314
      */
11315
0
      if (ctxt->redefCounter != 0) {
11316
0
          xmlChar *str = NULL;
11317
11318
0
          xmlSchemaCustomErr(ACTXT_CAST ctxt,
11319
0
        XML_SCHEMAP_SRC_REDEFINE, child, NULL,
11320
0
        "The redefining model group definition "
11321
0
        "'%s' must not contain more than one "
11322
0
        "reference to the redefined definition",
11323
0
        xmlSchemaFormatQName(&str,
11324
0
            ctxt->redef->refTargetNs,
11325
0
            ctxt->redef->refName),
11326
0
        NULL);
11327
0
          FREE_AND_NULL(str)
11328
0
          part = NULL;
11329
0
      } else if (((WXS_PARTICLE(part))->minOccurs != 1) ||
11330
0
          ((WXS_PARTICLE(part))->maxOccurs != 1))
11331
0
      {
11332
0
          xmlChar *str = NULL;
11333
          /*
11334
          * SPEC src-redefine:
11335
          * (6.1.2) "The `actual value` of both that
11336
          * group's minOccurs and maxOccurs [attribute]
11337
          * must be 1 (or `absent`).
11338
          */
11339
0
          xmlSchemaCustomErr(ACTXT_CAST ctxt,
11340
0
        XML_SCHEMAP_SRC_REDEFINE, child, NULL,
11341
0
        "The redefining model group definition "
11342
0
        "'%s' must not contain a reference to the "
11343
0
        "redefined definition with a "
11344
0
        "maxOccurs/minOccurs other than 1",
11345
0
        xmlSchemaFormatQName(&str,
11346
0
            ctxt->redef->refTargetNs,
11347
0
            ctxt->redef->refName),
11348
0
        NULL);
11349
0
          FREE_AND_NULL(str)
11350
0
          part = NULL;
11351
0
      }
11352
0
      ctxt->redef->reference = WXS_BASIC_CAST part;
11353
0
      ctxt->redefCounter++;
11354
0
        }
11355
0
    }
11356
0
      } else if (IS_SCHEMA(child, "any")) {
11357
0
    part = (xmlSchemaTreeItemPtr)
11358
0
        xmlSchemaParseAny(ctxt, schema, child);
11359
0
      } else if (IS_SCHEMA(child, "choice")) {
11360
0
    part = xmlSchemaParseModelGroup(ctxt, schema, child,
11361
0
        XML_SCHEMA_TYPE_CHOICE, 1);
11362
0
      } else if (IS_SCHEMA(child, "sequence")) {
11363
0
    part = xmlSchemaParseModelGroup(ctxt, schema, child,
11364
0
        XML_SCHEMA_TYPE_SEQUENCE, 1);
11365
0
      }
11366
0
      if (part != NULL) {
11367
0
    if (last == NULL)
11368
0
        item->children = part;
11369
0
    else
11370
0
        last->next = part;
11371
0
    last = part;
11372
0
      }
11373
0
      child = child->next;
11374
0
  }
11375
0
  if (child != NULL) {
11376
0
      xmlSchemaPContentErr(ctxt,
11377
0
    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11378
0
    NULL, node, child, NULL,
11379
0
    "(annotation?, (element | group | choice | sequence | any)*)");
11380
0
  }
11381
0
    }
11382
0
    if ((max == 0) && (min == 0))
11383
0
  return (NULL);
11384
0
    if (hasRefs) {
11385
  /*
11386
  * We need to resolve references.
11387
  */
11388
0
  WXS_ADD_PENDING(ctxt, item);
11389
0
    }
11390
0
    if (withParticle)
11391
0
  return ((xmlSchemaTreeItemPtr) particle);
11392
0
    else
11393
0
  return ((xmlSchemaTreeItemPtr) item);
11394
0
}
11395
11396
/**
11397
 * xmlSchemaParseRestriction:
11398
 * @ctxt:  a schema validation context
11399
 * @schema:  the schema being built
11400
 * @node:  a subtree containing XML Schema information
11401
 *
11402
 * parse a XML schema Restriction definition
11403
 * *WARNING* this interface is highly subject to change
11404
 *
11405
 * Returns the type definition or NULL in case of error
11406
 */
11407
static xmlSchemaTypePtr
11408
xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
11409
                          xmlNodePtr node, xmlSchemaTypeType parentType)
11410
0
{
11411
0
    xmlSchemaTypePtr type;
11412
0
    xmlNodePtr child = NULL;
11413
0
    xmlAttrPtr attr;
11414
11415
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
11416
0
        return (NULL);
11417
    /* Not a component, don't create it. */
11418
0
    type = ctxt->ctxtType;
11419
0
    type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION;
11420
11421
    /*
11422
    * Check for illegal attributes.
11423
    */
11424
0
    attr = node->properties;
11425
0
    while (attr != NULL) {
11426
0
  if (attr->ns == NULL) {
11427
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
11428
0
    (!xmlStrEqual(attr->name, BAD_CAST "base"))) {
11429
0
    xmlSchemaPIllegalAttrErr(ctxt,
11430
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11431
0
      }
11432
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
11433
0
      xmlSchemaPIllegalAttrErr(ctxt,
11434
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11435
0
  }
11436
0
  attr = attr->next;
11437
0
    }
11438
    /*
11439
    * Extract and validate attributes.
11440
    */
11441
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
11442
    /*
11443
    * Attribute
11444
    */
11445
    /*
11446
    * Extract the base type. The "base" attribute is mandatory if inside
11447
    * a complex type or if redefining.
11448
    *
11449
    * SPEC (1.2) "...otherwise (<restriction> has no <simpleType> "
11450
    * among its [children]), the simple type definition which is
11451
    * the {content type} of the type definition `resolved` to by
11452
    * the `actual value` of the base [attribute]"
11453
    */
11454
0
    if (xmlSchemaPValAttrQName(ctxt, schema, NULL, node, "base",
11455
0
  &(type->baseNs), &(type->base)) == 0)
11456
0
    {
11457
0
  if ((type->base == NULL) && (type->type == XML_SCHEMA_TYPE_COMPLEX)) {
11458
0
      xmlSchemaPMissingAttrErr(ctxt,
11459
0
    XML_SCHEMAP_S4S_ATTR_MISSING,
11460
0
    NULL, node, "base", NULL);
11461
0
  } else if ((ctxt->isRedefine) &&
11462
0
      (type->flags & XML_SCHEMAS_TYPE_GLOBAL))
11463
0
  {
11464
0
      if (type->base == NULL) {
11465
0
    xmlSchemaPMissingAttrErr(ctxt,
11466
0
        XML_SCHEMAP_S4S_ATTR_MISSING,
11467
0
        NULL, node, "base", NULL);
11468
0
      } else if ((! xmlStrEqual(type->base, type->name)) ||
11469
0
    (! xmlStrEqual(type->baseNs, type->targetNamespace)))
11470
0
      {
11471
0
    xmlChar *str1 = NULL, *str2 = NULL;
11472
    /*
11473
    * REDEFINE: SPEC src-redefine (5)
11474
    * "Within the [children], each <simpleType> must have a
11475
    * <restriction> among its [children] ... the `actual value` of
11476
    * whose base [attribute] must be the same as the `actual value`
11477
    * of its own name attribute plus target namespace;"
11478
    */
11479
0
    xmlSchemaPCustomErrExt(ctxt, XML_SCHEMAP_SRC_REDEFINE,
11480
0
        NULL, node, "This is a redefinition, but the QName "
11481
0
        "value '%s' of the 'base' attribute does not match the "
11482
0
        "type's designation '%s'",
11483
0
        xmlSchemaFormatQName(&str1, type->baseNs, type->base),
11484
0
        xmlSchemaFormatQName(&str2, type->targetNamespace,
11485
0
      type->name), NULL);
11486
0
    FREE_AND_NULL(str1);
11487
0
    FREE_AND_NULL(str2);
11488
    /* Avoid confusion and erase the values. */
11489
0
    type->base = NULL;
11490
0
    type->baseNs = NULL;
11491
0
      }
11492
0
  }
11493
0
    }
11494
    /*
11495
    * And now for the children...
11496
    */
11497
0
    child = node->children;
11498
0
    if (IS_SCHEMA(child, "annotation")) {
11499
  /*
11500
  * Add the annotation to the simple type ancestor.
11501
  */
11502
0
  xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
11503
0
      xmlSchemaParseAnnotation(ctxt, child, 1));
11504
0
        child = child->next;
11505
0
    }
11506
0
    if (parentType == XML_SCHEMA_TYPE_SIMPLE) {
11507
  /*
11508
  * Corresponds to <simpleType><restriction><simpleType>.
11509
  */
11510
0
  if (IS_SCHEMA(child, "simpleType")) {
11511
0
      if (type->base != NULL) {
11512
    /*
11513
    * src-restriction-base-or-simpleType
11514
    * Either the base [attribute] or the simpleType [child] of the
11515
    * <restriction> element must be present, but not both.
11516
    */
11517
0
    xmlSchemaPContentErr(ctxt,
11518
0
        XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE,
11519
0
        NULL, node, child,
11520
0
        "The attribute 'base' and the <simpleType> child are "
11521
0
        "mutually exclusive", NULL);
11522
0
      } else {
11523
0
    type->baseType = (xmlSchemaTypePtr)
11524
0
        xmlSchemaParseSimpleType(ctxt, schema, child, 0);
11525
0
      }
11526
0
      child = child->next;
11527
0
  } else if (type->base == NULL) {
11528
0
      xmlSchemaPContentErr(ctxt,
11529
0
    XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE,
11530
0
    NULL, node, child,
11531
0
    "Either the attribute 'base' or a <simpleType> child "
11532
0
    "must be present", NULL);
11533
0
  }
11534
0
    } else if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
11535
  /*
11536
  * Corresponds to <complexType><complexContent><restriction>...
11537
  * followed by:
11538
  *
11539
  * Model groups <all>, <choice> and <sequence>.
11540
  */
11541
0
  if (IS_SCHEMA(child, "all")) {
11542
0
      type->subtypes = (xmlSchemaTypePtr)
11543
0
    xmlSchemaParseModelGroup(ctxt, schema, child,
11544
0
        XML_SCHEMA_TYPE_ALL, 1);
11545
0
      child = child->next;
11546
0
  } else if (IS_SCHEMA(child, "choice")) {
11547
0
      type->subtypes = (xmlSchemaTypePtr)
11548
0
    xmlSchemaParseModelGroup(ctxt,
11549
0
        schema, child, XML_SCHEMA_TYPE_CHOICE, 1);
11550
0
      child = child->next;
11551
0
  } else if (IS_SCHEMA(child, "sequence")) {
11552
0
      type->subtypes = (xmlSchemaTypePtr)
11553
0
    xmlSchemaParseModelGroup(ctxt, schema, child,
11554
0
        XML_SCHEMA_TYPE_SEQUENCE, 1);
11555
0
      child = child->next;
11556
  /*
11557
  * Model group reference <group>.
11558
  */
11559
0
  } else if (IS_SCHEMA(child, "group")) {
11560
0
      type->subtypes = (xmlSchemaTypePtr)
11561
0
    xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
11562
      /*
11563
      * Note that the reference will be resolved in
11564
      * xmlSchemaResolveTypeReferences();
11565
      */
11566
0
      child = child->next;
11567
0
  }
11568
0
    } else if (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT) {
11569
  /*
11570
  * Corresponds to <complexType><simpleContent><restriction>...
11571
  *
11572
  * "1.1 the simple type definition corresponding to the <simpleType>
11573
  * among the [children] of <restriction> if there is one;"
11574
  */
11575
0
  if (IS_SCHEMA(child, "simpleType")) {
11576
      /*
11577
      * We will store the to-be-restricted simple type in
11578
      * type->contentTypeDef *temporarily*.
11579
      */
11580
0
      type->contentTypeDef = (xmlSchemaTypePtr)
11581
0
    xmlSchemaParseSimpleType(ctxt, schema, child, 0);
11582
0
      if ( type->contentTypeDef == NULL)
11583
0
    return (NULL);
11584
0
      child = child->next;
11585
0
  }
11586
0
    }
11587
11588
0
    if ((parentType == XML_SCHEMA_TYPE_SIMPLE) ||
11589
0
  (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT)) {
11590
0
  xmlSchemaFacetPtr facet, lastfacet = NULL;
11591
  /*
11592
  * Corresponds to <complexType><simpleContent><restriction>...
11593
  * <simpleType><restriction>...
11594
  */
11595
11596
  /*
11597
  * Add the facets to the simple type ancestor.
11598
  */
11599
  /*
11600
  * TODO: Datatypes: 4.1.3 Constraints on XML Representation of
11601
  * Simple Type Definition Schema Representation Constraint:
11602
  * *Single Facet Value*
11603
  */
11604
0
  while ((IS_SCHEMA(child, "minInclusive")) ||
11605
0
      (IS_SCHEMA(child, "minExclusive")) ||
11606
0
      (IS_SCHEMA(child, "maxInclusive")) ||
11607
0
      (IS_SCHEMA(child, "maxExclusive")) ||
11608
0
      (IS_SCHEMA(child, "totalDigits")) ||
11609
0
      (IS_SCHEMA(child, "fractionDigits")) ||
11610
0
      (IS_SCHEMA(child, "pattern")) ||
11611
0
      (IS_SCHEMA(child, "enumeration")) ||
11612
0
      (IS_SCHEMA(child, "whiteSpace")) ||
11613
0
      (IS_SCHEMA(child, "length")) ||
11614
0
      (IS_SCHEMA(child, "maxLength")) ||
11615
0
      (IS_SCHEMA(child, "minLength"))) {
11616
0
      facet = xmlSchemaParseFacet(ctxt, schema, child);
11617
0
      if (facet != NULL) {
11618
0
    if (lastfacet == NULL)
11619
0
        type->facets = facet;
11620
0
    else
11621
0
        lastfacet->next = facet;
11622
0
    lastfacet = facet;
11623
0
    lastfacet->next = NULL;
11624
0
      }
11625
0
      child = child->next;
11626
0
  }
11627
  /*
11628
  * Create links for derivation and validation.
11629
  */
11630
0
  if (type->facets != NULL) {
11631
0
      xmlSchemaFacetLinkPtr facetLink, lastFacetLink = NULL;
11632
11633
0
      facet = type->facets;
11634
0
      do {
11635
0
    facetLink = (xmlSchemaFacetLinkPtr)
11636
0
        xmlMalloc(sizeof(xmlSchemaFacetLink));
11637
0
    if (facetLink == NULL) {
11638
0
        xmlSchemaPErrMemory(ctxt);
11639
0
        xmlFree(facetLink);
11640
0
        return (NULL);
11641
0
    }
11642
0
    facetLink->facet = facet;
11643
0
    facetLink->next = NULL;
11644
0
    if (lastFacetLink == NULL)
11645
0
        type->facetSet = facetLink;
11646
0
    else
11647
0
        lastFacetLink->next = facetLink;
11648
0
    lastFacetLink = facetLink;
11649
0
    facet = facet->next;
11650
0
      } while (facet != NULL);
11651
0
  }
11652
0
    }
11653
0
    if (type->type == XML_SCHEMA_TYPE_COMPLEX) {
11654
  /*
11655
  * Attribute uses/declarations.
11656
  */
11657
0
  if (xmlSchemaParseLocalAttributes(ctxt, schema, &child,
11658
0
      (xmlSchemaItemListPtr *) &(type->attrUses),
11659
0
      XML_SCHEMA_TYPE_RESTRICTION, NULL) == -1)
11660
0
      return(NULL);
11661
  /*
11662
  * Attribute wildcard.
11663
  */
11664
0
  if (IS_SCHEMA(child, "anyAttribute")) {
11665
0
      type->attributeWildcard =
11666
0
    xmlSchemaParseAnyAttribute(ctxt, schema, child);
11667
0
      child = child->next;
11668
0
  }
11669
0
    }
11670
0
    if (child != NULL) {
11671
0
  if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
11672
0
      xmlSchemaPContentErr(ctxt,
11673
0
    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11674
0
    NULL, node, child, NULL,
11675
0
    "annotation?, (group | all | choice | sequence)?, "
11676
0
    "((attribute | attributeGroup)*, anyAttribute?))");
11677
0
  } else if (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT) {
11678
0
       xmlSchemaPContentErr(ctxt,
11679
0
    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11680
0
    NULL, node, child, NULL,
11681
0
    "(annotation?, (simpleType?, (minExclusive | minInclusive | "
11682
0
    "maxExclusive | maxInclusive | totalDigits | fractionDigits | "
11683
0
    "length | minLength | maxLength | enumeration | whiteSpace | "
11684
0
    "pattern)*)?, ((attribute | attributeGroup)*, anyAttribute?))");
11685
0
  } else {
11686
      /* Simple type */
11687
0
      xmlSchemaPContentErr(ctxt,
11688
0
    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11689
0
    NULL, node, child, NULL,
11690
0
    "(annotation?, (simpleType?, (minExclusive | minInclusive | "
11691
0
    "maxExclusive | maxInclusive | totalDigits | fractionDigits | "
11692
0
    "length | minLength | maxLength | enumeration | whiteSpace | "
11693
0
    "pattern)*))");
11694
0
  }
11695
0
    }
11696
0
    return (NULL);
11697
0
}
11698
11699
/**
11700
 * xmlSchemaParseExtension:
11701
 * @ctxt:  a schema validation context
11702
 * @schema:  the schema being built
11703
 * @node:  a subtree containing XML Schema information
11704
 *
11705
 * Parses an <extension>, which is found inside a
11706
 * <simpleContent> or <complexContent>.
11707
 * *WARNING* this interface is highly subject to change.
11708
 *
11709
 * TODO: Returns the type definition or NULL in case of error
11710
 */
11711
static xmlSchemaTypePtr
11712
xmlSchemaParseExtension(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
11713
                        xmlNodePtr node, xmlSchemaTypeType parentType)
11714
0
{
11715
0
    xmlSchemaTypePtr type;
11716
0
    xmlNodePtr child = NULL;
11717
0
    xmlAttrPtr attr;
11718
11719
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
11720
0
        return (NULL);
11721
    /* Not a component, don't create it. */
11722
0
    type = ctxt->ctxtType;
11723
0
    type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION;
11724
11725
    /*
11726
    * Check for illegal attributes.
11727
    */
11728
0
    attr = node->properties;
11729
0
    while (attr != NULL) {
11730
0
  if (attr->ns == NULL) {
11731
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
11732
0
    (!xmlStrEqual(attr->name, BAD_CAST "base"))) {
11733
0
    xmlSchemaPIllegalAttrErr(ctxt,
11734
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11735
0
      }
11736
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
11737
0
      xmlSchemaPIllegalAttrErr(ctxt,
11738
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11739
0
  }
11740
0
  attr = attr->next;
11741
0
    }
11742
11743
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
11744
11745
    /*
11746
    * Attribute "base" - mandatory.
11747
    */
11748
0
    if ((xmlSchemaPValAttrQName(ctxt, schema, NULL, node,
11749
0
  "base", &(type->baseNs), &(type->base)) == 0) &&
11750
0
  (type->base == NULL)) {
11751
0
  xmlSchemaPMissingAttrErr(ctxt,
11752
0
      XML_SCHEMAP_S4S_ATTR_MISSING,
11753
0
      NULL, node, "base", NULL);
11754
0
    }
11755
    /*
11756
    * And now for the children...
11757
    */
11758
0
    child = node->children;
11759
0
    if (IS_SCHEMA(child, "annotation")) {
11760
  /*
11761
  * Add the annotation to the type ancestor.
11762
  */
11763
0
  xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
11764
0
      xmlSchemaParseAnnotation(ctxt, child, 1));
11765
0
        child = child->next;
11766
0
    }
11767
0
    if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
11768
  /*
11769
  * Corresponds to <complexType><complexContent><extension>... and:
11770
  *
11771
  * Model groups <all>, <choice>, <sequence> and <group>.
11772
  */
11773
0
  if (IS_SCHEMA(child, "all")) {
11774
0
      type->subtypes = (xmlSchemaTypePtr)
11775
0
    xmlSchemaParseModelGroup(ctxt, schema,
11776
0
        child, XML_SCHEMA_TYPE_ALL, 1);
11777
0
      child = child->next;
11778
0
  } else if (IS_SCHEMA(child, "choice")) {
11779
0
      type->subtypes = (xmlSchemaTypePtr)
11780
0
    xmlSchemaParseModelGroup(ctxt, schema,
11781
0
        child, XML_SCHEMA_TYPE_CHOICE, 1);
11782
0
      child = child->next;
11783
0
  } else if (IS_SCHEMA(child, "sequence")) {
11784
0
      type->subtypes = (xmlSchemaTypePtr)
11785
0
    xmlSchemaParseModelGroup(ctxt, schema,
11786
0
    child, XML_SCHEMA_TYPE_SEQUENCE, 1);
11787
0
      child = child->next;
11788
0
  } else if (IS_SCHEMA(child, "group")) {
11789
0
      type->subtypes = (xmlSchemaTypePtr)
11790
0
    xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
11791
      /*
11792
      * Note that the reference will be resolved in
11793
      * xmlSchemaResolveTypeReferences();
11794
      */
11795
0
      child = child->next;
11796
0
  }
11797
0
    }
11798
0
    if (child != NULL) {
11799
  /*
11800
  * Attribute uses/declarations.
11801
  */
11802
0
  if (xmlSchemaParseLocalAttributes(ctxt, schema, &child,
11803
0
      (xmlSchemaItemListPtr *) &(type->attrUses),
11804
0
      XML_SCHEMA_TYPE_EXTENSION, NULL) == -1)
11805
0
      return(NULL);
11806
  /*
11807
  * Attribute wildcard.
11808
  */
11809
0
  if (IS_SCHEMA(child, "anyAttribute")) {
11810
0
      ctxt->ctxtType->attributeWildcard =
11811
0
    xmlSchemaParseAnyAttribute(ctxt, schema, child);
11812
0
      child = child->next;
11813
0
  }
11814
0
    }
11815
0
    if (child != NULL) {
11816
0
  if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
11817
      /* Complex content extension. */
11818
0
      xmlSchemaPContentErr(ctxt,
11819
0
    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11820
0
    NULL, node, child, NULL,
11821
0
    "(annotation?, ((group | all | choice | sequence)?, "
11822
0
    "((attribute | attributeGroup)*, anyAttribute?)))");
11823
0
  } else {
11824
      /* Simple content extension. */
11825
0
      xmlSchemaPContentErr(ctxt,
11826
0
    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11827
0
    NULL, node, child, NULL,
11828
0
    "(annotation?, ((attribute | attributeGroup)*, "
11829
0
    "anyAttribute?))");
11830
0
  }
11831
0
    }
11832
0
    return (NULL);
11833
0
}
11834
11835
/**
11836
 * xmlSchemaParseSimpleContent:
11837
 * @ctxt:  a schema validation context
11838
 * @schema:  the schema being built
11839
 * @node:  a subtree containing XML Schema information
11840
 *
11841
 * parse a XML schema SimpleContent definition
11842
 * *WARNING* this interface is highly subject to change
11843
 *
11844
 * Returns the type definition or NULL in case of error
11845
 */
11846
static int
11847
xmlSchemaParseSimpleContent(xmlSchemaParserCtxtPtr ctxt,
11848
                            xmlSchemaPtr schema, xmlNodePtr node,
11849
          int *hasRestrictionOrExtension)
11850
0
{
11851
0
    xmlSchemaTypePtr type;
11852
0
    xmlNodePtr child = NULL;
11853
0
    xmlAttrPtr attr;
11854
11855
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL) ||
11856
0
  (hasRestrictionOrExtension == NULL))
11857
0
        return (-1);
11858
0
    *hasRestrictionOrExtension = 0;
11859
    /* Not a component, don't create it. */
11860
0
    type = ctxt->ctxtType;
11861
0
    type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
11862
    /*
11863
    * Check for illegal attributes.
11864
    */
11865
0
    attr = node->properties;
11866
0
    while (attr != NULL) {
11867
0
  if (attr->ns == NULL) {
11868
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "id"))) {
11869
0
    xmlSchemaPIllegalAttrErr(ctxt,
11870
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11871
0
      }
11872
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
11873
0
      xmlSchemaPIllegalAttrErr(ctxt,
11874
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11875
0
  }
11876
0
  attr = attr->next;
11877
0
    }
11878
11879
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
11880
11881
    /*
11882
    * And now for the children...
11883
    */
11884
0
    child = node->children;
11885
0
    if (IS_SCHEMA(child, "annotation")) {
11886
  /*
11887
  * Add the annotation to the complex type ancestor.
11888
  */
11889
0
  xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
11890
0
      xmlSchemaParseAnnotation(ctxt, child, 1));
11891
0
        child = child->next;
11892
0
    }
11893
0
    if (child == NULL) {
11894
0
  xmlSchemaPContentErr(ctxt,
11895
0
      XML_SCHEMAP_S4S_ELEM_MISSING,
11896
0
      NULL, node, NULL, NULL,
11897
0
      "(annotation?, (restriction | extension))");
11898
0
    }
11899
0
    if (child == NULL) {
11900
0
  xmlSchemaPContentErr(ctxt,
11901
0
      XML_SCHEMAP_S4S_ELEM_MISSING,
11902
0
      NULL, node, NULL, NULL,
11903
0
      "(annotation?, (restriction | extension))");
11904
0
    }
11905
0
    if (IS_SCHEMA(child, "restriction")) {
11906
0
        xmlSchemaParseRestriction(ctxt, schema, child,
11907
0
      XML_SCHEMA_TYPE_SIMPLE_CONTENT);
11908
0
  (*hasRestrictionOrExtension) = 1;
11909
0
        child = child->next;
11910
0
    } else if (IS_SCHEMA(child, "extension")) {
11911
0
        xmlSchemaParseExtension(ctxt, schema, child,
11912
0
      XML_SCHEMA_TYPE_SIMPLE_CONTENT);
11913
0
  (*hasRestrictionOrExtension) = 1;
11914
0
        child = child->next;
11915
0
    }
11916
0
    if (child != NULL) {
11917
0
  xmlSchemaPContentErr(ctxt,
11918
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11919
0
      NULL, node, child, NULL,
11920
0
      "(annotation?, (restriction | extension))");
11921
0
    }
11922
0
    return (0);
11923
0
}
11924
11925
/**
11926
 * xmlSchemaParseComplexContent:
11927
 * @ctxt:  a schema validation context
11928
 * @schema:  the schema being built
11929
 * @node:  a subtree containing XML Schema information
11930
 *
11931
 * parse a XML schema ComplexContent definition
11932
 * *WARNING* this interface is highly subject to change
11933
 *
11934
 * Returns the type definition or NULL in case of error
11935
 */
11936
static int
11937
xmlSchemaParseComplexContent(xmlSchemaParserCtxtPtr ctxt,
11938
                             xmlSchemaPtr schema, xmlNodePtr node,
11939
           int *hasRestrictionOrExtension)
11940
0
{
11941
0
    xmlSchemaTypePtr type;
11942
0
    xmlNodePtr child = NULL;
11943
0
    xmlAttrPtr attr;
11944
11945
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL) ||
11946
0
  (hasRestrictionOrExtension == NULL))
11947
0
        return (-1);
11948
0
    *hasRestrictionOrExtension = 0;
11949
    /* Not a component, don't create it. */
11950
0
    type = ctxt->ctxtType;
11951
    /*
11952
    * Check for illegal attributes.
11953
    */
11954
0
    attr = node->properties;
11955
0
    while (attr != NULL) {
11956
0
  if (attr->ns == NULL) {
11957
0
      if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
11958
0
    (!xmlStrEqual(attr->name, BAD_CAST "mixed")))
11959
0
      {
11960
0
    xmlSchemaPIllegalAttrErr(ctxt,
11961
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11962
0
      }
11963
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
11964
0
      xmlSchemaPIllegalAttrErr(ctxt,
11965
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11966
0
  }
11967
0
  attr = attr->next;
11968
0
    }
11969
11970
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
11971
11972
    /*
11973
    * Set the 'mixed' on the complex type ancestor.
11974
    */
11975
0
    if (xmlGetBooleanProp(ctxt, node, "mixed", 0))  {
11976
0
  if ((type->flags & XML_SCHEMAS_TYPE_MIXED) == 0)
11977
0
      type->flags |= XML_SCHEMAS_TYPE_MIXED;
11978
0
    }
11979
0
    child = node->children;
11980
0
    if (IS_SCHEMA(child, "annotation")) {
11981
  /*
11982
  * Add the annotation to the complex type ancestor.
11983
  */
11984
0
  xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
11985
0
      xmlSchemaParseAnnotation(ctxt, child, 1));
11986
0
        child = child->next;
11987
0
    }
11988
0
    if (child == NULL) {
11989
0
  xmlSchemaPContentErr(ctxt,
11990
0
      XML_SCHEMAP_S4S_ELEM_MISSING,
11991
0
      NULL, node, NULL,
11992
0
      NULL, "(annotation?, (restriction | extension))");
11993
0
    }
11994
0
    if (child == NULL) {
11995
0
  xmlSchemaPContentErr(ctxt,
11996
0
      XML_SCHEMAP_S4S_ELEM_MISSING,
11997
0
      NULL, node, NULL,
11998
0
      NULL, "(annotation?, (restriction | extension))");
11999
0
    }
12000
0
    if (IS_SCHEMA(child, "restriction")) {
12001
0
        xmlSchemaParseRestriction(ctxt, schema, child,
12002
0
      XML_SCHEMA_TYPE_COMPLEX_CONTENT);
12003
0
  (*hasRestrictionOrExtension) = 1;
12004
0
        child = child->next;
12005
0
    } else if (IS_SCHEMA(child, "extension")) {
12006
0
        xmlSchemaParseExtension(ctxt, schema, child,
12007
0
      XML_SCHEMA_TYPE_COMPLEX_CONTENT);
12008
0
  (*hasRestrictionOrExtension) = 1;
12009
0
        child = child->next;
12010
0
    }
12011
0
    if (child != NULL) {
12012
0
  xmlSchemaPContentErr(ctxt,
12013
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
12014
0
      NULL, node, child,
12015
0
      NULL, "(annotation?, (restriction | extension))");
12016
0
    }
12017
0
    return (0);
12018
0
}
12019
12020
/**
12021
 * xmlSchemaParseComplexType:
12022
 * @ctxt:  a schema validation context
12023
 * @schema:  the schema being built
12024
 * @node:  a subtree containing XML Schema information
12025
 *
12026
 * parse a XML schema Complex Type definition
12027
 * *WARNING* this interface is highly subject to change
12028
 *
12029
 * Returns the type definition or NULL in case of error
12030
 */
12031
static xmlSchemaTypePtr
12032
xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
12033
                          xmlNodePtr node, int topLevel)
12034
0
{
12035
0
    xmlSchemaTypePtr type, ctxtType;
12036
0
    xmlNodePtr child = NULL;
12037
0
    const xmlChar *name = NULL;
12038
0
    xmlAttrPtr attr;
12039
0
    const xmlChar *attrValue;
12040
#ifdef ENABLE_NAMED_LOCALS
12041
    char buf[40];
12042
#endif
12043
0
    int final = 0, block = 0, hasRestrictionOrExtension = 0;
12044
12045
12046
0
    if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
12047
0
        return (NULL);
12048
12049
0
    ctxtType = ctxt->ctxtType;
12050
12051
0
    if (topLevel) {
12052
0
  attr = xmlSchemaGetPropNode(node, "name");
12053
0
  if (attr == NULL) {
12054
0
      xmlSchemaPMissingAttrErr(ctxt,
12055
0
    XML_SCHEMAP_S4S_ATTR_MISSING, NULL, node, "name", NULL);
12056
0
      return (NULL);
12057
0
  } else if (xmlSchemaPValAttrNode(ctxt, NULL, attr,
12058
0
      xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
12059
0
      return (NULL);
12060
0
  }
12061
0
    }
12062
12063
0
    if (topLevel == 0) {
12064
  /*
12065
  * Parse as local complex type definition.
12066
  */
12067
#ifdef ENABLE_NAMED_LOCALS
12068
        snprintf(buf, 39, "#CT%d", ctxt->counter++ + 1);
12069
  type = xmlSchemaAddType(ctxt, schema,
12070
      XML_SCHEMA_TYPE_COMPLEX,
12071
      xmlDictLookup(ctxt->dict, (const xmlChar *)buf, -1),
12072
      ctxt->targetNamespace, node, 0);
12073
#else
12074
0
  type = xmlSchemaAddType(ctxt, schema,
12075
0
      XML_SCHEMA_TYPE_COMPLEX,
12076
0
      NULL, ctxt->targetNamespace, node, 0);
12077
0
#endif
12078
0
  if (type == NULL)
12079
0
      return (NULL);
12080
0
  name = type->name;
12081
0
  type->node = node;
12082
0
  type->type = XML_SCHEMA_TYPE_COMPLEX;
12083
  /*
12084
  * TODO: We need the target namespace.
12085
  */
12086
0
    } else {
12087
  /*
12088
  * Parse as global complex type definition.
12089
  */
12090
0
  type = xmlSchemaAddType(ctxt, schema,
12091
0
      XML_SCHEMA_TYPE_COMPLEX,
12092
0
      name, ctxt->targetNamespace, node, 1);
12093
0
  if (type == NULL)
12094
0
      return (NULL);
12095
0
  type->node = node;
12096
0
  type->type = XML_SCHEMA_TYPE_COMPLEX;
12097
0
  type->flags |= XML_SCHEMAS_TYPE_GLOBAL;
12098
0
    }
12099
0
    type->targetNamespace = ctxt->targetNamespace;
12100
    /*
12101
    * Handle attributes.
12102
    */
12103
0
    attr = node->properties;
12104
0
    while (attr != NULL) {
12105
0
  if (attr->ns == NULL) {
12106
0
      if (xmlStrEqual(attr->name, BAD_CAST "id")) {
12107
    /*
12108
    * Attribute "id".
12109
    */
12110
0
    xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
12111
0
      } else if (xmlStrEqual(attr->name, BAD_CAST "mixed")) {
12112
    /*
12113
    * Attribute "mixed".
12114
    */
12115
0
    if (xmlSchemaPGetBoolNodeValue(ctxt,
12116
0
      NULL, (xmlNodePtr) attr))
12117
0
        type->flags |= XML_SCHEMAS_TYPE_MIXED;
12118
0
      } else if (topLevel) {
12119
    /*
12120
    * Attributes of global complex type definitions.
12121
    */
12122
0
    if (xmlStrEqual(attr->name, BAD_CAST "name")) {
12123
        /* Pass. */
12124
0
    } else if (xmlStrEqual(attr->name, BAD_CAST "abstract")) {
12125
        /*
12126
        * Attribute "abstract".
12127
        */
12128
0
        if (xmlSchemaPGetBoolNodeValue(ctxt,
12129
0
          NULL, (xmlNodePtr) attr))
12130
0
      type->flags |= XML_SCHEMAS_TYPE_ABSTRACT;
12131
0
    } else if (xmlStrEqual(attr->name, BAD_CAST "final")) {
12132
        /*
12133
        * Attribute "final".
12134
        */
12135
0
        attrValue = xmlSchemaGetNodeContent(ctxt,
12136
0
      (xmlNodePtr) attr);
12137
0
        if (xmlSchemaPValAttrBlockFinal(attrValue,
12138
0
      &(type->flags),
12139
0
      -1,
12140
0
      XML_SCHEMAS_TYPE_FINAL_EXTENSION,
12141
0
      XML_SCHEMAS_TYPE_FINAL_RESTRICTION,
12142
0
      -1, -1, -1) != 0)
12143
0
        {
12144
0
      xmlSchemaPSimpleTypeErr(ctxt,
12145
0
          XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
12146
0
          NULL, (xmlNodePtr) attr, NULL,
12147
0
          "(#all | List of (extension | restriction))",
12148
0
          attrValue, NULL, NULL, NULL);
12149
0
        } else
12150
0
      final = 1;
12151
0
    } else if (xmlStrEqual(attr->name, BAD_CAST "block")) {
12152
        /*
12153
        * Attribute "block".
12154
        */
12155
0
        attrValue = xmlSchemaGetNodeContent(ctxt,
12156
0
      (xmlNodePtr) attr);
12157
0
        if (xmlSchemaPValAttrBlockFinal(attrValue, &(type->flags),
12158
0
      -1,
12159
0
      XML_SCHEMAS_TYPE_BLOCK_EXTENSION,
12160
0
      XML_SCHEMAS_TYPE_BLOCK_RESTRICTION,
12161
0
      -1, -1, -1) != 0) {
12162
0
      xmlSchemaPSimpleTypeErr(ctxt,
12163
0
          XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
12164
0
          NULL, (xmlNodePtr) attr, NULL,
12165
0
          "(#all | List of (extension | restriction)) ",
12166
0
          attrValue, NULL, NULL, NULL);
12167
0
        } else
12168
0
      block = 1;
12169
0
    } else {
12170
0
      xmlSchemaPIllegalAttrErr(ctxt,
12171
0
          XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
12172
0
    }
12173
0
      } else {
12174
0
    xmlSchemaPIllegalAttrErr(ctxt,
12175
0
        XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
12176
0
      }
12177
0
  } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
12178
0
      xmlSchemaPIllegalAttrErr(ctxt,
12179
0
    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
12180
0
  }
12181
0
  attr = attr->next;
12182
0
    }
12183
0
    if (! block) {
12184
  /*
12185
  * Apply default "block" values.
12186
  */
12187
0
  if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION)
12188
0
      type->flags |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
12189
0
  if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION)
12190
0
      type->flags |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
12191
0
    }
12192
0
    if (! final) {
12193
  /*
12194
  * Apply default "block" values.
12195
  */
12196
0
  if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
12197
0
      type->flags |= XML_SCHEMAS_TYPE_FINAL_RESTRICTION;
12198
0
  if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION)
12199
0
      type->flags |= XML_SCHEMAS_TYPE_FINAL_EXTENSION;
12200
0
    }
12201
    /*
12202
    * And now for the children...
12203
    */
12204
0
    child = node->children;
12205
0
    if (IS_SCHEMA(child, "annotation")) {
12206
0
        type->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
12207
0
        child = child->next;
12208
0
    }
12209
0
    ctxt->ctxtType = type;
12210
0
    if (IS_SCHEMA(child, "simpleContent")) {
12211
  /*
12212
  * <complexType><simpleContent>...
12213
  * 3.4.3 : 2.2
12214
  * Specifying mixed='true' when the <simpleContent>
12215
  * alternative is chosen has no effect
12216
  */
12217
0
  if (type->flags & XML_SCHEMAS_TYPE_MIXED)
12218
0
      type->flags ^= XML_SCHEMAS_TYPE_MIXED;
12219
0
        xmlSchemaParseSimpleContent(ctxt, schema, child,
12220
0
      &hasRestrictionOrExtension);
12221
0
        child = child->next;
12222
0
    } else if (IS_SCHEMA(child, "complexContent")) {
12223
  /*
12224
  * <complexType><complexContent>...
12225
  */
12226
0
  type->contentType = XML_SCHEMA_CONTENT_EMPTY;
12227
0
        xmlSchemaParseComplexContent(ctxt, schema, child,
12228
0
      &hasRestrictionOrExtension);
12229
0
        child = child->next;
12230
0
    } else {
12231
  /*
12232
  * E.g <complexType><sequence>... or <complexType><attribute>... etc.
12233
  *
12234
  * SPEC
12235
  * "...the third alternative (neither <simpleContent> nor
12236
  * <complexContent>) is chosen. This case is understood as shorthand
12237
  * for complex content restricting the `ur-type definition`, and the
12238
  * details of the mappings should be modified as necessary.
12239
  */
12240
0
  type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
12241
0
  type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION;
12242
  /*
12243
  * Parse model groups.
12244
  */
12245
0
        if (IS_SCHEMA(child, "all")) {
12246
0
            type->subtypes = (xmlSchemaTypePtr)
12247
0
    xmlSchemaParseModelGroup(ctxt, schema, child,
12248
0
        XML_SCHEMA_TYPE_ALL, 1);
12249
0
            child = child->next;
12250
0
        } else if (IS_SCHEMA(child, "choice")) {
12251
0
            type->subtypes = (xmlSchemaTypePtr)
12252
0
    xmlSchemaParseModelGroup(ctxt, schema, child,
12253
0
        XML_SCHEMA_TYPE_CHOICE, 1);
12254
0
            child = child->next;
12255
0
        } else if (IS_SCHEMA(child, "sequence")) {
12256
0
            type->subtypes = (xmlSchemaTypePtr)
12257
0
    xmlSchemaParseModelGroup(ctxt, schema, child,
12258
0
        XML_SCHEMA_TYPE_SEQUENCE, 1);
12259
0
            child = child->next;
12260
0
        } else if (IS_SCHEMA(child, "group")) {
12261
0
            type->subtypes = (xmlSchemaTypePtr)
12262
0
    xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
12263
      /*
12264
      * Note that the reference will be resolved in
12265
      * xmlSchemaResolveTypeReferences();
12266
      */
12267
0
            child = child->next;
12268
0
        }
12269
  /*
12270
  * Parse attribute decls/refs.
12271
  */
12272
0
        if (xmlSchemaParseLocalAttributes(ctxt, schema, &child,
12273
0
      (xmlSchemaItemListPtr *) &(type->attrUses),
12274
0
      XML_SCHEMA_TYPE_RESTRICTION, NULL) == -1)
12275
0
      return(NULL);
12276
  /*
12277
  * Parse attribute wildcard.
12278
  */
12279
0
  if (IS_SCHEMA(child, "anyAttribute")) {
12280
0
      type->attributeWildcard = xmlSchemaParseAnyAttribute(ctxt, schema, child);
12281
0
      child = child->next;
12282
0
  }
12283
0
    }
12284
0
    if (child != NULL) {
12285
0
  xmlSchemaPContentErr(ctxt,
12286
0
      XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
12287
0
      NULL, node, child,
12288
0
      NULL, "(annotation?, (simpleContent | complexContent | "
12289
0
      "((group | all | choice | sequence)?, ((attribute | "
12290
0
      "attributeGroup)*, anyAttribute?))))");
12291
0
    }
12292
    /*
12293
    * REDEFINE: SPEC src-redefine (5)
12294
    */
12295
0
    if (topLevel && ctxt->isRedefine && (! hasRestrictionOrExtension)) {
12296
0
  xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE,
12297
0
      NULL, node, "This is a redefinition, thus the "
12298
0
      "<complexType> must have a <restriction> or <extension> "
12299
0
      "grand-child", NULL);
12300
0
    }
12301
0
    ctxt->ctxtType = ctxtType;
12302
0
    return (type);
12303
0
}
12304
12305
/************************************************************************
12306
 *                  *
12307
 *      Validating using Schemas      *
12308
 *                  *
12309
 ************************************************************************/
12310
12311
/************************************************************************
12312
 *                  *
12313
 *      Reading/Writing Schemas       *
12314
 *                  *
12315
 ************************************************************************/
12316
12317
#if 0 /* Will be enabled if it is clear what options are needed. */
12318
/**
12319
 * xmlSchemaParserCtxtSetOptions:
12320
 * @ctxt: a schema parser context
12321
 * @options: a combination of xmlSchemaParserOption
12322
 *
12323
 * Sets the options to be used during the parse.
12324
 *
12325
 * Returns 0 in case of success, -1 in case of an
12326
 * API error.
12327
 */
12328
static int
12329
xmlSchemaParserCtxtSetOptions(xmlSchemaParserCtxtPtr ctxt,
12330
            int options)
12331
12332
{
12333
    int i;
12334
12335
    if (ctxt == NULL)
12336
  return (-1);
12337
    /*
12338
    * WARNING: Change the start value if adding to the
12339
    * xmlSchemaParseOption.
12340
    */
12341
    for (i = 1; i < (int) sizeof(int) * 8; i++) {
12342
        if (options & 1<<i) {
12343
      return (-1);
12344
        }
12345
    }
12346
    ctxt->options = options;
12347
    return (0);
12348
}
12349
12350
/**
12351
 * xmlSchemaValidCtxtGetOptions:
12352
 * @ctxt: a schema parser context
12353
 *
12354
 * Returns the option combination of the parser context.
12355
 */
12356
static int
12357
xmlSchemaParserCtxtGetOptions(xmlSchemaParserCtxtPtr ctxt)
12358
12359
{
12360
    if (ctxt == NULL)
12361
  return (-1);
12362
    else
12363
  return (ctxt->options);
12364
}
12365
#endif
12366
12367
/**
12368
 * xmlSchemaNewParserCtxt:
12369
 * @URL:  the location of the schema
12370
 *
12371
 * Create an XML Schemas parse context for that file/resource expected
12372
 * to contain an XML Schemas file.
12373
 *
12374
 * Returns the parser context or NULL in case of error
12375
 */
12376
xmlSchemaParserCtxtPtr
12377
xmlSchemaNewParserCtxt(const char *URL)
12378
0
{
12379
0
    xmlSchemaParserCtxtPtr ret;
12380
12381
0
    if (URL == NULL)
12382
0
        return (NULL);
12383
12384
0
    ret = xmlSchemaParserCtxtCreate();
12385
0
    if (ret == NULL)
12386
0
  return(NULL);
12387
0
    ret->dict = xmlDictCreate();
12388
0
    ret->URL = xmlDictLookup(ret->dict, (const xmlChar *) URL, -1);
12389
0
    return (ret);
12390
0
}
12391
12392
/**
12393
 * xmlSchemaNewMemParserCtxt:
12394
 * @buffer:  a pointer to a char array containing the schemas
12395
 * @size:  the size of the array
12396
 *
12397
 * Create an XML Schemas parse context for that memory buffer expected
12398
 * to contain an XML Schemas file.
12399
 *
12400
 * Returns the parser context or NULL in case of error
12401
 */
12402
xmlSchemaParserCtxtPtr
12403
xmlSchemaNewMemParserCtxt(const char *buffer, int size)
12404
0
{
12405
0
    xmlSchemaParserCtxtPtr ret;
12406
12407
0
    if ((buffer == NULL) || (size <= 0))
12408
0
        return (NULL);
12409
0
    ret = xmlSchemaParserCtxtCreate();
12410
0
    if (ret == NULL)
12411
0
  return(NULL);
12412
0
    ret->buffer = buffer;
12413
0
    ret->size = size;
12414
0
    ret->dict = xmlDictCreate();
12415
0
    return (ret);
12416
0
}
12417
12418
/**
12419
 * xmlSchemaNewDocParserCtxt:
12420
 * @doc:  a preparsed document tree
12421
 *
12422
 * Create an XML Schemas parse context for that document.
12423
 * NB. The document may be modified during the parsing process.
12424
 *
12425
 * Returns the parser context or NULL in case of error
12426
 */
12427
xmlSchemaParserCtxtPtr
12428
xmlSchemaNewDocParserCtxt(xmlDocPtr doc)
12429
0
{
12430
0
    xmlSchemaParserCtxtPtr ret;
12431
12432
0
    if (doc == NULL)
12433
0
      return (NULL);
12434
0
    ret = xmlSchemaParserCtxtCreate();
12435
0
    if (ret == NULL)
12436
0
  return(NULL);
12437
0
    ret->doc = doc;
12438
0
    ret->dict = xmlDictCreate();
12439
    /* The application has responsibility for the document */
12440
0
    ret->preserve = 1;
12441
12442
0
    return (ret);
12443
0
}
12444
12445
/**
12446
 * xmlSchemaFreeParserCtxt:
12447
 * @ctxt:  the schema parser context
12448
 *
12449
 * Free the resources associated to the schema parser context
12450
 */
12451
void
12452
xmlSchemaFreeParserCtxt(xmlSchemaParserCtxtPtr ctxt)
12453
0
{
12454
0
    if (ctxt == NULL)
12455
0
        return;
12456
0
    if (ctxt->doc != NULL && !ctxt->preserve)
12457
0
        xmlFreeDoc(ctxt->doc);
12458
0
    if (ctxt->vctxt != NULL) {
12459
0
  xmlSchemaFreeValidCtxt(ctxt->vctxt);
12460
0
    }
12461
0
    if (ctxt->ownsConstructor && (ctxt->constructor != NULL)) {
12462
0
  xmlSchemaConstructionCtxtFree(ctxt->constructor);
12463
0
  ctxt->constructor = NULL;
12464
0
  ctxt->ownsConstructor = 0;
12465
0
    }
12466
0
    if (ctxt->attrProhibs != NULL)
12467
0
  xmlSchemaItemListFree(ctxt->attrProhibs);
12468
0
    xmlDictFree(ctxt->dict);
12469
0
    xmlFree(ctxt);
12470
0
}
12471
12472
/************************************************************************
12473
 *                  *
12474
 *      Building the content models     *
12475
 *                  *
12476
 ************************************************************************/
12477
12478
/**
12479
 * xmlSchemaBuildContentModelForSubstGroup:
12480
 *
12481
 * Returns 1 if nillable, 0 otherwise
12482
 */
12483
static int
12484
xmlSchemaBuildContentModelForSubstGroup(xmlSchemaParserCtxtPtr pctxt,
12485
  xmlSchemaParticlePtr particle, int counter, xmlAutomataStatePtr end)
12486
0
{
12487
0
    xmlAutomataStatePtr start, tmp;
12488
0
    xmlSchemaElementPtr elemDecl, member;
12489
0
    xmlSchemaSubstGroupPtr substGroup;
12490
0
    int i;
12491
0
    int ret = 0;
12492
12493
0
    elemDecl = (xmlSchemaElementPtr) particle->children;
12494
    /*
12495
    * Wrap the substitution group with a CHOICE.
12496
    */
12497
0
    start = pctxt->state;
12498
0
    if (end == NULL)
12499
0
  end = xmlAutomataNewState(pctxt->am);
12500
0
    substGroup = xmlSchemaSubstGroupGet(pctxt, elemDecl);
12501
0
    if (substGroup == NULL) {
12502
0
  xmlSchemaPErr(pctxt, WXS_ITEM_NODE(particle),
12503
0
      XML_SCHEMAP_INTERNAL,
12504
0
      "Internal error: xmlSchemaBuildContentModelForSubstGroup, "
12505
0
      "declaration is marked having a subst. group but none "
12506
0
      "available.\n", elemDecl->name, NULL);
12507
0
  return(0);
12508
0
    }
12509
0
    if (counter >= 0) {
12510
  /*
12511
  * NOTE that we put the declaration in, even if it's abstract.
12512
  * However, an error will be raised during *validation* if an element
12513
  * information item shall be validated against an abstract element
12514
  * declaration.
12515
  */
12516
0
  tmp = xmlAutomataNewCountedTrans(pctxt->am, start, NULL, counter);
12517
0
        xmlAutomataNewTransition2(pctxt->am, tmp, end,
12518
0
              elemDecl->name, elemDecl->targetNamespace, elemDecl);
12519
  /*
12520
  * Add subst. group members.
12521
  */
12522
0
  for (i = 0; i < substGroup->members->nbItems; i++) {
12523
0
      member = (xmlSchemaElementPtr) substGroup->members->items[i];
12524
0
            xmlAutomataNewTransition2(pctxt->am, tmp, end,
12525
0
                   member->name, member->targetNamespace, member);
12526
0
  }
12527
0
    } else if (particle->maxOccurs == 1) {
12528
  /*
12529
  * NOTE that we put the declaration in, even if it's abstract,
12530
  */
12531
0
  xmlAutomataNewEpsilon(pctxt->am,
12532
0
      xmlAutomataNewTransition2(pctxt->am,
12533
0
      start, NULL,
12534
0
      elemDecl->name, elemDecl->targetNamespace, elemDecl), end);
12535
  /*
12536
  * Add subst. group members.
12537
  */
12538
0
  for (i = 0; i < substGroup->members->nbItems; i++) {
12539
0
      member = (xmlSchemaElementPtr) substGroup->members->items[i];
12540
      /*
12541
      * NOTE: This fixes bug #341150. xmlAutomataNewOnceTrans2()
12542
      *  was incorrectly used instead of xmlAutomataNewTransition2()
12543
      *  (seems like a copy&paste bug from the XML_SCHEMA_TYPE_ALL
12544
      *  section in xmlSchemaBuildAContentModel() ).
12545
      * TODO: Check if xmlAutomataNewOnceTrans2() was instead
12546
      *  intended for the above "counter" section originally. I.e.,
12547
      *  check xs:all with subst-groups.
12548
      *
12549
      * tmp = xmlAutomataNewOnceTrans2(pctxt->am, start, NULL,
12550
      *                member->name, member->targetNamespace,
12551
      *          1, 1, member);
12552
      */
12553
0
      tmp = xmlAutomataNewTransition2(pctxt->am, start, NULL,
12554
0
    member->name, member->targetNamespace, member);
12555
0
      xmlAutomataNewEpsilon(pctxt->am, tmp, end);
12556
0
  }
12557
0
    } else {
12558
0
  xmlAutomataStatePtr hop;
12559
0
  int maxOccurs = particle->maxOccurs == UNBOUNDED ?
12560
0
      UNBOUNDED : particle->maxOccurs - 1;
12561
0
  int minOccurs = particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
12562
12563
0
  counter =
12564
0
      xmlAutomataNewCounter(pctxt->am, minOccurs,
12565
0
      maxOccurs);
12566
0
  hop = xmlAutomataNewState(pctxt->am);
12567
12568
0
  xmlAutomataNewEpsilon(pctxt->am,
12569
0
      xmlAutomataNewTransition2(pctxt->am,
12570
0
      start, NULL,
12571
0
      elemDecl->name, elemDecl->targetNamespace, elemDecl),
12572
0
      hop);
12573
  /*
12574
   * Add subst. group members.
12575
   */
12576
0
  for (i = 0; i < substGroup->members->nbItems; i++) {
12577
0
      member = (xmlSchemaElementPtr) substGroup->members->items[i];
12578
0
      xmlAutomataNewEpsilon(pctxt->am,
12579
0
    xmlAutomataNewTransition2(pctxt->am,
12580
0
    start, NULL,
12581
0
    member->name, member->targetNamespace, member),
12582
0
    hop);
12583
0
  }
12584
0
  xmlAutomataNewCountedTrans(pctxt->am, hop, start, counter);
12585
0
  xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter);
12586
0
    }
12587
0
    if (particle->minOccurs == 0) {
12588
0
  xmlAutomataNewEpsilon(pctxt->am, start, end);
12589
0
        ret = 1;
12590
0
    }
12591
0
    pctxt->state = end;
12592
0
    return(ret);
12593
0
}
12594
12595
/**
12596
 * xmlSchemaBuildContentModelForElement:
12597
 *
12598
 * Returns 1 if nillable, 0 otherwise
12599
 */
12600
static int
12601
xmlSchemaBuildContentModelForElement(xmlSchemaParserCtxtPtr ctxt,
12602
             xmlSchemaParticlePtr particle)
12603
0
{
12604
0
    int ret = 0;
12605
12606
0
    if (((xmlSchemaElementPtr) particle->children)->flags &
12607
0
  XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) {
12608
  /*
12609
  * Substitution groups.
12610
  */
12611
0
  ret = xmlSchemaBuildContentModelForSubstGroup(ctxt, particle, -1, NULL);
12612
0
    } else {
12613
0
  xmlSchemaElementPtr elemDecl;
12614
0
  xmlAutomataStatePtr start;
12615
12616
0
  elemDecl = (xmlSchemaElementPtr) particle->children;
12617
12618
0
  if (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT)
12619
0
      return(0);
12620
0
  if (particle->maxOccurs == 1) {
12621
0
      start = ctxt->state;
12622
0
      ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL,
12623
0
        elemDecl->name, elemDecl->targetNamespace, elemDecl);
12624
0
  } else if ((particle->maxOccurs >= UNBOUNDED) &&
12625
0
             (particle->minOccurs < 2)) {
12626
      /* Special case. */
12627
0
      start = ctxt->state;
12628
0
      ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL,
12629
0
    elemDecl->name, elemDecl->targetNamespace, elemDecl);
12630
0
      ctxt->state = xmlAutomataNewTransition2(ctxt->am, ctxt->state, ctxt->state,
12631
0
    elemDecl->name, elemDecl->targetNamespace, elemDecl);
12632
0
  } else {
12633
0
      int counter;
12634
0
      int maxOccurs = particle->maxOccurs == UNBOUNDED ?
12635
0
          UNBOUNDED : particle->maxOccurs - 1;
12636
0
      int minOccurs = particle->minOccurs < 1 ?
12637
0
          0 : particle->minOccurs - 1;
12638
12639
0
      start = xmlAutomataNewEpsilon(ctxt->am, ctxt->state, NULL);
12640
0
      counter = xmlAutomataNewCounter(ctxt->am, minOccurs, maxOccurs);
12641
0
      ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL,
12642
0
    elemDecl->name, elemDecl->targetNamespace, elemDecl);
12643
0
      xmlAutomataNewCountedTrans(ctxt->am, ctxt->state, start, counter);
12644
0
      ctxt->state = xmlAutomataNewCounterTrans(ctxt->am, ctxt->state,
12645
0
    NULL, counter);
12646
0
  }
12647
0
  if (particle->minOccurs == 0) {
12648
0
      xmlAutomataNewEpsilon(ctxt->am, start, ctxt->state);
12649
0
            ret = 1;
12650
0
        }
12651
0
    }
12652
0
    return(ret);
12653
0
}
12654
12655
/**
12656
 * xmlSchemaBuildAContentModel:
12657
 * @ctxt:  the schema parser context
12658
 * @particle:  the particle component
12659
 * @name:  the complex type's name whose content is being built
12660
 *
12661
 * Create the automaton for the {content type} of a complex type.
12662
 *
12663
 * Returns 1 if the content is nillable, 0 otherwise
12664
 */
12665
static int
12666
xmlSchemaBuildAContentModel(xmlSchemaParserCtxtPtr pctxt,
12667
          xmlSchemaParticlePtr particle)
12668
0
{
12669
0
    int ret = 0, tmp2;
12670
12671
0
    if (particle == NULL) {
12672
0
  PERROR_INT("xmlSchemaBuildAContentModel", "particle is NULL");
12673
0
  return(1);
12674
0
    }
12675
0
    if (particle->children == NULL) {
12676
  /*
12677
  * Just return in this case. A missing "term" of the particle
12678
  * might arise due to an invalid "term" component.
12679
  */
12680
0
  return(1);
12681
0
    }
12682
12683
0
    switch (particle->children->type) {
12684
0
  case XML_SCHEMA_TYPE_ANY: {
12685
0
      xmlAutomataStatePtr start, end;
12686
0
      xmlSchemaWildcardPtr wild;
12687
0
      xmlSchemaWildcardNsPtr ns;
12688
12689
0
      wild = (xmlSchemaWildcardPtr) particle->children;
12690
12691
0
      start = pctxt->state;
12692
0
      end = xmlAutomataNewState(pctxt->am);
12693
12694
0
      if (particle->maxOccurs == 1) {
12695
0
    if (wild->any == 1) {
12696
        /*
12697
        * We need to add both transitions:
12698
        *
12699
        * 1. the {"*", "*"} for elements in a namespace.
12700
        */
12701
0
        pctxt->state =
12702
0
      xmlAutomataNewTransition2(pctxt->am,
12703
0
      start, NULL, BAD_CAST "*", BAD_CAST "*", wild);
12704
0
        xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
12705
        /*
12706
        * 2. the {"*"} for elements in no namespace.
12707
        */
12708
0
        pctxt->state =
12709
0
      xmlAutomataNewTransition2(pctxt->am,
12710
0
      start, NULL, BAD_CAST "*", NULL, wild);
12711
0
        xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
12712
12713
0
    } else if (wild->nsSet != NULL) {
12714
0
        ns = wild->nsSet;
12715
0
        do {
12716
0
      pctxt->state = start;
12717
0
      pctxt->state = xmlAutomataNewTransition2(pctxt->am,
12718
0
          pctxt->state, NULL, BAD_CAST "*", ns->value, wild);
12719
0
      xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
12720
0
      ns = ns->next;
12721
0
        } while (ns != NULL);
12722
12723
0
    } else if (wild->negNsSet != NULL) {
12724
0
        pctxt->state = xmlAutomataNewNegTrans(pctxt->am,
12725
0
      start, end, BAD_CAST "*", wild->negNsSet->value,
12726
0
      wild);
12727
0
    }
12728
0
      } else {
12729
0
    int counter;
12730
0
    xmlAutomataStatePtr hop;
12731
0
    int maxOccurs =
12732
0
        particle->maxOccurs == UNBOUNDED ? UNBOUNDED :
12733
0
                                           particle->maxOccurs - 1;
12734
0
    int minOccurs =
12735
0
        particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
12736
12737
0
    counter = xmlAutomataNewCounter(pctxt->am, minOccurs, maxOccurs);
12738
0
    hop = xmlAutomataNewState(pctxt->am);
12739
0
    if (wild->any == 1) {
12740
0
        pctxt->state =
12741
0
      xmlAutomataNewTransition2(pctxt->am,
12742
0
      start, NULL, BAD_CAST "*", BAD_CAST "*", wild);
12743
0
        xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
12744
0
        pctxt->state =
12745
0
      xmlAutomataNewTransition2(pctxt->am,
12746
0
      start, NULL, BAD_CAST "*", NULL, wild);
12747
0
        xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
12748
0
    } else if (wild->nsSet != NULL) {
12749
0
        ns = wild->nsSet;
12750
0
        do {
12751
0
      pctxt->state =
12752
0
          xmlAutomataNewTransition2(pctxt->am,
12753
0
        start, NULL, BAD_CAST "*", ns->value, wild);
12754
0
      xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
12755
0
      ns = ns->next;
12756
0
        } while (ns != NULL);
12757
12758
0
    } else if (wild->negNsSet != NULL) {
12759
0
        pctxt->state = xmlAutomataNewNegTrans(pctxt->am,
12760
0
      start, hop, BAD_CAST "*", wild->negNsSet->value,
12761
0
      wild);
12762
0
    }
12763
0
    xmlAutomataNewCountedTrans(pctxt->am, hop, start, counter);
12764
0
    xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter);
12765
0
      }
12766
0
      if (particle->minOccurs == 0) {
12767
0
    xmlAutomataNewEpsilon(pctxt->am, start, end);
12768
0
                ret = 1;
12769
0
      }
12770
0
      pctxt->state = end;
12771
0
            break;
12772
0
  }
12773
0
        case XML_SCHEMA_TYPE_ELEMENT:
12774
0
      ret = xmlSchemaBuildContentModelForElement(pctxt, particle);
12775
0
      break;
12776
0
        case XML_SCHEMA_TYPE_SEQUENCE:{
12777
0
            xmlSchemaTreeItemPtr sub;
12778
12779
0
            ret = 1;
12780
            /*
12781
             * If max and min occurrences are default (1) then
12782
             * simply iterate over the particles of the <sequence>.
12783
             */
12784
0
            if ((particle->minOccurs == 1) && (particle->maxOccurs == 1)) {
12785
0
                sub = particle->children->children;
12786
12787
0
                while (sub != NULL) {
12788
0
                    tmp2 = xmlSchemaBuildAContentModel(pctxt,
12789
0
                                        (xmlSchemaParticlePtr) sub);
12790
0
                    if (tmp2 != 1) ret = 0;
12791
0
                    sub = sub->next;
12792
0
                }
12793
0
            } else {
12794
0
                xmlAutomataStatePtr oldstate = pctxt->state;
12795
12796
0
                if (particle->maxOccurs >= UNBOUNDED) {
12797
0
                    if (particle->minOccurs > 1) {
12798
0
                        xmlAutomataStatePtr tmp;
12799
0
                        int counter;
12800
12801
0
                        pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
12802
0
                            oldstate, NULL);
12803
0
                        oldstate = pctxt->state;
12804
12805
0
                        counter = xmlAutomataNewCounter(pctxt->am,
12806
0
                            particle->minOccurs - 1, UNBOUNDED);
12807
12808
0
                        sub = particle->children->children;
12809
0
                        while (sub != NULL) {
12810
0
                            tmp2 = xmlSchemaBuildAContentModel(pctxt,
12811
0
                                            (xmlSchemaParticlePtr) sub);
12812
0
                            if (tmp2 != 1) ret = 0;
12813
0
                            sub = sub->next;
12814
0
                        }
12815
0
                        tmp = pctxt->state;
12816
0
                        xmlAutomataNewCountedTrans(pctxt->am, tmp,
12817
0
                                                   oldstate, counter);
12818
0
                        pctxt->state =
12819
0
                            xmlAutomataNewCounterTrans(pctxt->am, tmp,
12820
0
                                                       NULL, counter);
12821
0
                        if (ret == 1)
12822
0
                            xmlAutomataNewEpsilon(pctxt->am,
12823
0
                                                oldstate, pctxt->state);
12824
12825
0
                    } else {
12826
0
                        pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
12827
0
                            oldstate, NULL);
12828
0
                        oldstate = pctxt->state;
12829
12830
0
                        sub = particle->children->children;
12831
0
                        while (sub != NULL) {
12832
0
                            tmp2 = xmlSchemaBuildAContentModel(pctxt,
12833
0
                                        (xmlSchemaParticlePtr) sub);
12834
0
                            if (tmp2 != 1) ret = 0;
12835
0
                            sub = sub->next;
12836
0
                        }
12837
0
                        xmlAutomataNewEpsilon(pctxt->am, pctxt->state,
12838
0
                                              oldstate);
12839
                        /*
12840
                         * epsilon needed to block previous trans from
12841
                         * being allowed to enter back from another
12842
                         * construct
12843
                         */
12844
0
                        pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
12845
0
                                            pctxt->state, NULL);
12846
0
                        if (particle->minOccurs == 0) {
12847
0
                            xmlAutomataNewEpsilon(pctxt->am,
12848
0
                                oldstate, pctxt->state);
12849
0
                            ret = 1;
12850
0
                        }
12851
0
                    }
12852
0
                } else if ((particle->maxOccurs > 1)
12853
0
                           || (particle->minOccurs > 1)) {
12854
0
                    xmlAutomataStatePtr tmp;
12855
0
                    int counter;
12856
12857
0
                    pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
12858
0
                        oldstate, NULL);
12859
0
                    oldstate = pctxt->state;
12860
12861
0
                    counter = xmlAutomataNewCounter(pctxt->am,
12862
0
                        particle->minOccurs - 1,
12863
0
                        particle->maxOccurs - 1);
12864
12865
0
                    sub = particle->children->children;
12866
0
                    while (sub != NULL) {
12867
0
                        tmp2 = xmlSchemaBuildAContentModel(pctxt,
12868
0
                                        (xmlSchemaParticlePtr) sub);
12869
0
                        if (tmp2 != 1) ret = 0;
12870
0
                        sub = sub->next;
12871
0
                    }
12872
0
                    tmp = pctxt->state;
12873
0
                    xmlAutomataNewCountedTrans(pctxt->am,
12874
0
                        tmp, oldstate, counter);
12875
0
                    pctxt->state =
12876
0
                        xmlAutomataNewCounterTrans(pctxt->am, tmp, NULL,
12877
0
                                                   counter);
12878
0
                    if ((particle->minOccurs == 0) || (ret == 1)) {
12879
0
                        xmlAutomataNewEpsilon(pctxt->am,
12880
0
                                            oldstate, pctxt->state);
12881
0
                        ret = 1;
12882
0
                    }
12883
0
                } else {
12884
0
                    sub = particle->children->children;
12885
0
                    while (sub != NULL) {
12886
0
                        tmp2 = xmlSchemaBuildAContentModel(pctxt,
12887
0
                                        (xmlSchemaParticlePtr) sub);
12888
0
                        if (tmp2 != 1) ret = 0;
12889
0
                        sub = sub->next;
12890
0
                    }
12891
12892
        /*
12893
         * epsilon needed to block previous trans from
12894
         * being allowed to enter back from another
12895
         * construct
12896
         */
12897
0
        pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
12898
0
          pctxt->state, NULL);
12899
12900
0
                    if (particle->minOccurs == 0) {
12901
0
                        xmlAutomataNewEpsilon(pctxt->am, oldstate,
12902
0
                                              pctxt->state);
12903
0
                        ret = 1;
12904
0
                    }
12905
0
                }
12906
0
            }
12907
0
            break;
12908
0
        }
12909
0
        case XML_SCHEMA_TYPE_CHOICE:{
12910
0
            xmlSchemaTreeItemPtr sub;
12911
0
            xmlAutomataStatePtr start, end;
12912
12913
0
            ret = 0;
12914
0
            start = pctxt->state;
12915
0
            end = xmlAutomataNewState(pctxt->am);
12916
12917
            /*
12918
             * iterate over the subtypes and remerge the end with an
12919
             * epsilon transition
12920
             */
12921
0
            if (particle->maxOccurs == 1) {
12922
0
                sub = particle->children->children;
12923
0
                while (sub != NULL) {
12924
0
                    pctxt->state = start;
12925
0
                    tmp2 = xmlSchemaBuildAContentModel(pctxt,
12926
0
                                        (xmlSchemaParticlePtr) sub);
12927
0
                    if (tmp2 == 1) ret = 1;
12928
0
                    xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
12929
0
                    sub = sub->next;
12930
0
                }
12931
0
            } else {
12932
0
                int counter;
12933
0
                xmlAutomataStatePtr hop, base;
12934
0
                int maxOccurs = particle->maxOccurs == UNBOUNDED ?
12935
0
                    UNBOUNDED : particle->maxOccurs - 1;
12936
0
                int minOccurs =
12937
0
                    particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
12938
12939
                /*
12940
                 * use a counter to keep track of the number of transitions
12941
                 * which went through the choice.
12942
                 */
12943
0
                counter =
12944
0
                    xmlAutomataNewCounter(pctxt->am, minOccurs, maxOccurs);
12945
0
                hop = xmlAutomataNewState(pctxt->am);
12946
0
                base = xmlAutomataNewState(pctxt->am);
12947
12948
0
                sub = particle->children->children;
12949
0
                while (sub != NULL) {
12950
0
                    pctxt->state = base;
12951
0
                    tmp2 = xmlSchemaBuildAContentModel(pctxt,
12952
0
                                        (xmlSchemaParticlePtr) sub);
12953
0
                    if (tmp2 == 1) ret = 1;
12954
0
                    xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
12955
0
                    sub = sub->next;
12956
0
                }
12957
0
                xmlAutomataNewEpsilon(pctxt->am, start, base);
12958
0
                xmlAutomataNewCountedTrans(pctxt->am, hop, base, counter);
12959
0
                xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter);
12960
0
                if (ret == 1)
12961
0
                    xmlAutomataNewEpsilon(pctxt->am, base, end);
12962
0
            }
12963
0
            if (particle->minOccurs == 0) {
12964
0
                xmlAutomataNewEpsilon(pctxt->am, start, end);
12965
0
                ret = 1;
12966
0
            }
12967
0
            pctxt->state = end;
12968
0
            break;
12969
0
        }
12970
0
        case XML_SCHEMA_TYPE_ALL:{
12971
0
            xmlAutomataStatePtr start, tmp;
12972
0
            xmlSchemaParticlePtr sub;
12973
0
            xmlSchemaElementPtr elemDecl;
12974
12975
0
            ret = 1;
12976
12977
0
            sub = (xmlSchemaParticlePtr) particle->children->children;
12978
0
            if (sub == NULL)
12979
0
                break;
12980
12981
0
            ret = 0;
12982
12983
0
            start = pctxt->state;
12984
0
            tmp = xmlAutomataNewState(pctxt->am);
12985
0
            xmlAutomataNewEpsilon(pctxt->am, pctxt->state, tmp);
12986
0
            pctxt->state = tmp;
12987
0
            while (sub != NULL) {
12988
0
                pctxt->state = tmp;
12989
12990
0
                elemDecl = (xmlSchemaElementPtr) sub->children;
12991
0
                if (elemDecl == NULL) {
12992
0
                    PERROR_INT("xmlSchemaBuildAContentModel",
12993
0
                        "<element> particle has no term");
12994
0
                    return(ret);
12995
0
                };
12996
                /*
12997
                * NOTE: The {max occurs} of all the particles in the
12998
                * {particles} of the group must be 0 or 1; this is
12999
                * already ensured during the parse of the content of
13000
                * <all>.
13001
                */
13002
0
                if (elemDecl->flags & XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) {
13003
0
                    int counter;
13004
13005
                    /*
13006
                     * This is an abstract group, we need to share
13007
                     * the same counter for all the element transitions
13008
                     * derived from the group
13009
                     */
13010
0
                    counter = xmlAutomataNewCounter(pctxt->am,
13011
0
                                       sub->minOccurs, sub->maxOccurs);
13012
0
                    xmlSchemaBuildContentModelForSubstGroup(pctxt,
13013
0
                                       sub, counter, pctxt->state);
13014
0
                } else {
13015
0
                    if ((sub->minOccurs == 1) &&
13016
0
                        (sub->maxOccurs == 1)) {
13017
0
                        xmlAutomataNewOnceTrans2(pctxt->am, pctxt->state,
13018
0
                                                pctxt->state,
13019
0
                                                elemDecl->name,
13020
0
                                                elemDecl->targetNamespace,
13021
0
                                                1, 1, elemDecl);
13022
0
                    } else if ((sub->minOccurs == 0) &&
13023
0
                        (sub->maxOccurs == 1)) {
13024
13025
0
                        xmlAutomataNewCountTrans2(pctxt->am, pctxt->state,
13026
0
                                                 pctxt->state,
13027
0
                                                 elemDecl->name,
13028
0
                                                 elemDecl->targetNamespace,
13029
0
                                                 0,
13030
0
                                                 1,
13031
0
                                                 elemDecl);
13032
0
                    }
13033
0
                }
13034
0
                sub = (xmlSchemaParticlePtr) sub->next;
13035
0
            }
13036
0
            pctxt->state =
13037
0
                xmlAutomataNewAllTrans(pctxt->am, pctxt->state, NULL, 0);
13038
0
            if (particle->minOccurs == 0) {
13039
0
                xmlAutomataNewEpsilon(pctxt->am, start, pctxt->state);
13040
0
                ret = 1;
13041
0
            }
13042
0
            break;
13043
0
        }
13044
0
  case XML_SCHEMA_TYPE_GROUP:
13045
      /*
13046
      * If we hit a model group definition, then this means that
13047
      * it was empty, thus was not substituted for the containing
13048
      * model group. Just do nothing in this case.
13049
      * TODO: But the group should be substituted and not occur at
13050
      * all in the content model at this point. Fix this.
13051
      */
13052
0
            ret = 1;
13053
0
      break;
13054
0
        default:
13055
0
      xmlSchemaInternalErr2(ACTXT_CAST pctxt,
13056
0
    "xmlSchemaBuildAContentModel",
13057
0
    "found unexpected term of type '%s' in content model",
13058
0
    WXS_ITEM_TYPE_NAME(particle->children), NULL);
13059
0
            return(ret);
13060
0
    }
13061
0
    return(ret);
13062
0
}
13063
13064
/**
13065
 * xmlSchemaBuildContentModel:
13066
 * @ctxt:  the schema parser context
13067
 * @type:  the complex type definition
13068
 * @name:  the element name
13069
 *
13070
 * Builds the content model of the complex type.
13071
 */
13072
static void
13073
xmlSchemaBuildContentModel(xmlSchemaTypePtr type,
13074
         xmlSchemaParserCtxtPtr ctxt)
13075
0
{
13076
0
    if ((type->type != XML_SCHEMA_TYPE_COMPLEX) ||
13077
0
  (type->contModel != NULL) ||
13078
0
  ((type->contentType != XML_SCHEMA_CONTENT_ELEMENTS) &&
13079
0
  (type->contentType != XML_SCHEMA_CONTENT_MIXED)))
13080
0
  return;
13081
13082
0
    ctxt->am = NULL;
13083
0
    ctxt->am = xmlNewAutomata();
13084
0
    if (ctxt->am == NULL) {
13085
0
  xmlSchemaPErrMemory(ctxt);
13086
0
        return;
13087
0
    }
13088
0
    ctxt->state = xmlAutomataGetInitState(ctxt->am);
13089
    /*
13090
    * Build the automaton.
13091
    */
13092
0
    xmlSchemaBuildAContentModel(ctxt, WXS_TYPE_PARTICLE(type));
13093
0
    xmlAutomataSetFinalState(ctxt->am, ctxt->state);
13094
0
    type->contModel = xmlAutomataCompile(ctxt->am);
13095
0
    if (type->contModel == NULL) {
13096
0
        xmlSchemaPCustomErr(ctxt,
13097
0
      XML_SCHEMAP_INTERNAL,
13098
0
      WXS_BASIC_CAST type, type->node,
13099
0
      "Failed to compile the content model", NULL);
13100
0
    } else if (xmlRegexpIsDeterminist(type->contModel) != 1) {
13101
0
        xmlSchemaPCustomErr(ctxt,
13102
0
      XML_SCHEMAP_NOT_DETERMINISTIC,
13103
      /* XML_SCHEMAS_ERR_NOTDETERMINIST, */
13104
0
      WXS_BASIC_CAST type, type->node,
13105
0
      "The content model is not determinist", NULL);
13106
0
    } else {
13107
0
    }
13108
0
    ctxt->state = NULL;
13109
0
    xmlFreeAutomata(ctxt->am);
13110
0
    ctxt->am = NULL;
13111
0
}
13112
13113
/**
13114
 * xmlSchemaResolveElementReferences:
13115
 * @elem:  the schema element context
13116
 * @ctxt:  the schema parser context
13117
 *
13118
 * Resolves the references of an element declaration
13119
 * or particle, which has an element declaration as it's
13120
 * term.
13121
 */
13122
static void
13123
xmlSchemaResolveElementReferences(xmlSchemaElementPtr elemDecl,
13124
          xmlSchemaParserCtxtPtr ctxt)
13125
0
{
13126
0
    if ((ctxt == NULL) || (elemDecl == NULL) ||
13127
0
  ((elemDecl != NULL) &&
13128
0
  (elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_RESOLVED)))
13129
0
        return;
13130
0
    elemDecl->flags |= XML_SCHEMAS_ELEM_INTERNAL_RESOLVED;
13131
13132
0
    if ((elemDecl->subtypes == NULL) && (elemDecl->namedType != NULL)) {
13133
0
  xmlSchemaTypePtr type;
13134
13135
  /* (type definition) ... otherwise the type definition `resolved`
13136
  * to by the `actual value` of the type [attribute] ...
13137
  */
13138
0
  type = xmlSchemaGetType(ctxt->schema, elemDecl->namedType,
13139
0
      elemDecl->namedTypeNs);
13140
0
  if (type == NULL) {
13141
0
      xmlSchemaPResCompAttrErr(ctxt,
13142
0
    XML_SCHEMAP_SRC_RESOLVE,
13143
0
    WXS_BASIC_CAST elemDecl, elemDecl->node,
13144
0
    "type", elemDecl->namedType, elemDecl->namedTypeNs,
13145
0
    XML_SCHEMA_TYPE_BASIC, "type definition");
13146
0
  } else
13147
0
      elemDecl->subtypes = type;
13148
0
    }
13149
0
    if (elemDecl->substGroup != NULL) {
13150
0
  xmlSchemaElementPtr substHead;
13151
13152
  /*
13153
  * FIXME TODO: Do we need a new field in _xmlSchemaElement for
13154
  * substitutionGroup?
13155
  */
13156
0
  substHead = xmlSchemaGetElem(ctxt->schema, elemDecl->substGroup,
13157
0
      elemDecl->substGroupNs);
13158
0
  if (substHead == NULL) {
13159
0
      xmlSchemaPResCompAttrErr(ctxt,
13160
0
    XML_SCHEMAP_SRC_RESOLVE,
13161
0
    WXS_BASIC_CAST elemDecl, NULL,
13162
0
    "substitutionGroup", elemDecl->substGroup,
13163
0
    elemDecl->substGroupNs, XML_SCHEMA_TYPE_ELEMENT, NULL);
13164
0
  } else {
13165
0
      xmlSchemaResolveElementReferences(substHead, ctxt);
13166
      /*
13167
      * Set the "substitution group affiliation".
13168
      * NOTE that now we use the "refDecl" field for this.
13169
      */
13170
0
      WXS_SUBST_HEAD(elemDecl) = substHead;
13171
      /*
13172
      * The type definitions is set to:
13173
      * SPEC "...the {type definition} of the element
13174
      * declaration `resolved` to by the `actual value`
13175
      * of the substitutionGroup [attribute], if present"
13176
      */
13177
0
      if (elemDecl->subtypes == NULL) {
13178
0
                if (substHead->subtypes == NULL) {
13179
                    /*
13180
                     * This can happen with self-referencing substitution
13181
                     * groups. The cycle will be detected later, but we have
13182
                     * to set subtypes to avoid null-pointer dereferences.
13183
                     */
13184
0
              elemDecl->subtypes = xmlSchemaGetBuiltInType(
13185
0
                            XML_SCHEMAS_ANYTYPE);
13186
0
                } else {
13187
0
        elemDecl->subtypes = substHead->subtypes;
13188
0
                }
13189
0
            }
13190
0
  }
13191
0
    }
13192
    /*
13193
    * SPEC "The definition of anyType serves as the default type definition
13194
    * for element declarations whose XML representation does not specify one."
13195
    */
13196
0
    if ((elemDecl->subtypes == NULL) &&
13197
0
  (elemDecl->namedType == NULL) &&
13198
0
  (elemDecl->substGroup == NULL))
13199
0
  elemDecl->subtypes = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
13200
0
}
13201
13202
/**
13203
 * xmlSchemaResolveUnionMemberTypes:
13204
 * @ctxt:  the schema parser context
13205
 * @type:  the schema simple type definition
13206
 *
13207
 * Checks and builds the "member type definitions" property of the union
13208
 * simple type. This handles part (1), part (2) is done in
13209
 * xmlSchemaFinishMemberTypeDefinitionsProperty()
13210
 *
13211
 * Returns -1 in case of an internal error, 0 otherwise.
13212
 */
13213
static int
13214
xmlSchemaResolveUnionMemberTypes(xmlSchemaParserCtxtPtr ctxt,
13215
         xmlSchemaTypePtr type)
13216
0
{
13217
13218
0
    xmlSchemaTypeLinkPtr link, lastLink, newLink;
13219
0
    xmlSchemaTypePtr memberType;
13220
13221
    /*
13222
    * SPEC (1) "If the <union> alternative is chosen, then [Definition:]
13223
    * define the explicit members as the type definitions `resolved`
13224
    * to by the items in the `actual value` of the memberTypes [attribute],
13225
    * if any, followed by the type definitions corresponding to the
13226
    * <simpleType>s among the [children] of <union>, if any."
13227
    */
13228
    /*
13229
    * Resolve references.
13230
    */
13231
0
    link = type->memberTypes;
13232
0
    lastLink = NULL;
13233
0
    while (link != NULL) {
13234
0
  const xmlChar *name, *nsName;
13235
13236
0
  name = ((xmlSchemaQNameRefPtr) link->type)->name;
13237
0
  nsName = ((xmlSchemaQNameRefPtr) link->type)->targetNamespace;
13238
13239
0
  memberType = xmlSchemaGetType(ctxt->schema, name, nsName);
13240
0
  if ((memberType == NULL) || (! WXS_IS_SIMPLE(memberType))) {
13241
0
      xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE,
13242
0
    WXS_BASIC_CAST type, type->node, "memberTypes",
13243
0
    name, nsName, XML_SCHEMA_TYPE_SIMPLE, NULL);
13244
      /*
13245
      * Remove the member type link.
13246
      */
13247
0
      if (lastLink == NULL)
13248
0
    type->memberTypes = link->next;
13249
0
      else
13250
0
    lastLink->next = link->next;
13251
0
      newLink = link;
13252
0
      link = link->next;
13253
0
      xmlFree(newLink);
13254
0
  } else {
13255
0
      link->type = memberType;
13256
0
      lastLink = link;
13257
0
      link = link->next;
13258
0
  }
13259
0
    }
13260
    /*
13261
    * Add local simple types,
13262
    */
13263
0
    memberType = type->subtypes;
13264
0
    while (memberType != NULL) {
13265
0
  link = (xmlSchemaTypeLinkPtr) xmlMalloc(sizeof(xmlSchemaTypeLink));
13266
0
  if (link == NULL) {
13267
0
      xmlSchemaPErrMemory(ctxt);
13268
0
      return (-1);
13269
0
  }
13270
0
  link->type = memberType;
13271
0
  link->next = NULL;
13272
0
  if (lastLink == NULL)
13273
0
      type->memberTypes = link;
13274
0
  else
13275
0
      lastLink->next = link;
13276
0
  lastLink = link;
13277
0
  memberType = memberType->next;
13278
0
    }
13279
0
    return (0);
13280
0
}
13281
13282
/**
13283
 * xmlSchemaIsDerivedFromBuiltInType:
13284
 * @ctxt:  the schema parser context
13285
 * @type:  the type definition
13286
 * @valType: the value type
13287
 *
13288
 *
13289
 * Returns 1 if the type has the given value type, or
13290
 * is derived from such a type.
13291
 */
13292
static int
13293
xmlSchemaIsDerivedFromBuiltInType(xmlSchemaTypePtr type, int valType)
13294
0
{
13295
0
    if (type == NULL)
13296
0
  return (0);
13297
0
    if (WXS_IS_COMPLEX(type))
13298
0
  return (0);
13299
0
    if (type->type == XML_SCHEMA_TYPE_BASIC) {
13300
0
  if (type->builtInType == valType)
13301
0
      return(1);
13302
0
  if ((type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) ||
13303
0
      (type->builtInType == XML_SCHEMAS_ANYTYPE))
13304
0
      return (0);
13305
0
  return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType));
13306
0
    }
13307
0
    return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType));
13308
0
}
13309
13310
#if 0
13311
/**
13312
 * xmlSchemaIsDerivedFromBuiltInType:
13313
 * @ctxt:  the schema parser context
13314
 * @type:  the type definition
13315
 * @valType: the value type
13316
 *
13317
 *
13318
 * Returns 1 if the type has the given value type, or
13319
 * is derived from such a type.
13320
 */
13321
static int
13322
xmlSchemaIsUserDerivedFromBuiltInType(xmlSchemaTypePtr type, int valType)
13323
{
13324
    if (type == NULL)
13325
  return (0);
13326
    if (WXS_IS_COMPLEX(type))
13327
  return (0);
13328
    if (type->type == XML_SCHEMA_TYPE_BASIC) {
13329
  if (type->builtInType == valType)
13330
      return(1);
13331
  return (0);
13332
    } else
13333
  return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType));
13334
13335
    return (0);
13336
}
13337
13338
static xmlSchemaTypePtr
13339
xmlSchemaQueryBuiltInType(xmlSchemaTypePtr type)
13340
{
13341
    if (type == NULL)
13342
  return (NULL);
13343
    if (WXS_IS_COMPLEX(type))
13344
  return (NULL);
13345
    if (type->type == XML_SCHEMA_TYPE_BASIC)
13346
  return(type);
13347
    return(xmlSchemaQueryBuiltInType(type->subtypes));
13348
}
13349
#endif
13350
13351
/**
13352
 * xmlSchemaGetPrimitiveType:
13353
 * @type:  the simpleType definition
13354
 *
13355
 * Returns the primitive type of the given type or
13356
 * NULL in case of error.
13357
 */
13358
static xmlSchemaTypePtr
13359
xmlSchemaGetPrimitiveType(xmlSchemaTypePtr type)
13360
0
{
13361
13362
0
    while (type != NULL) {
13363
  /*
13364
  * Note that anySimpleType is actually not a primitive type
13365
  * but we need that here.
13366
  */
13367
0
  if ((type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) ||
13368
0
     (type->flags & XML_SCHEMAS_TYPE_BUILTIN_PRIMITIVE))
13369
0
      return (type);
13370
0
  type = type->baseType;
13371
0
    }
13372
13373
0
    return (NULL);
13374
0
}
13375
13376
#if 0
13377
/**
13378
 * xmlSchemaGetBuiltInTypeAncestor:
13379
 * @type:  the simpleType definition
13380
 *
13381
 * Returns the primitive type of the given type or
13382
 * NULL in case of error.
13383
 */
13384
static xmlSchemaTypePtr
13385
xmlSchemaGetBuiltInTypeAncestor(xmlSchemaTypePtr type)
13386
{
13387
    if (WXS_IS_LIST(type) || WXS_IS_UNION(type))
13388
  return (0);
13389
    while (type != NULL) {
13390
  if (type->type == XML_SCHEMA_TYPE_BASIC)
13391
      return (type);
13392
  type = type->baseType;
13393
    }
13394
13395
    return (NULL);
13396
}
13397
#endif
13398
13399
/**
13400
 * xmlSchemaCloneWildcardNsConstraints:
13401
 * @ctxt:  the schema parser context
13402
 * @dest:  the destination wildcard
13403
 * @source: the source wildcard
13404
 *
13405
 * Clones the namespace constraints of source
13406
 * and assigns them to dest.
13407
 * Returns -1 on internal error, 0 otherwise.
13408
 */
13409
static int
13410
xmlSchemaCloneWildcardNsConstraints(xmlSchemaParserCtxtPtr ctxt,
13411
            xmlSchemaWildcardPtr dest,
13412
            xmlSchemaWildcardPtr source)
13413
0
{
13414
0
    xmlSchemaWildcardNsPtr cur, tmp, last;
13415
13416
0
    if ((source == NULL) || (dest == NULL))
13417
0
  return(-1);
13418
0
    dest->any = source->any;
13419
0
    cur = source->nsSet;
13420
0
    last = NULL;
13421
0
    while (cur != NULL) {
13422
0
  tmp = xmlSchemaNewWildcardNsConstraint(ctxt);
13423
0
  if (tmp == NULL)
13424
0
      return(-1);
13425
0
  tmp->value = cur->value;
13426
0
  if (last == NULL)
13427
0
      dest->nsSet = tmp;
13428
0
  else
13429
0
      last->next = tmp;
13430
0
  last = tmp;
13431
0
  cur = cur->next;
13432
0
    }
13433
0
    if (dest->negNsSet != NULL)
13434
0
  xmlSchemaFreeWildcardNsSet(dest->negNsSet);
13435
0
    if (source->negNsSet != NULL) {
13436
0
  dest->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
13437
0
  if (dest->negNsSet == NULL)
13438
0
      return(-1);
13439
0
  dest->negNsSet->value = source->negNsSet->value;
13440
0
    } else
13441
0
  dest->negNsSet = NULL;
13442
0
    return(0);
13443
0
}
13444
13445
/**
13446
 * xmlSchemaUnionWildcards:
13447
 * @ctxt:  the schema parser context
13448
 * @completeWild:  the first wildcard
13449
 * @curWild: the second wildcard
13450
 *
13451
 * Unions the namespace constraints of the given wildcards.
13452
 * @completeWild will hold the resulting union.
13453
 * Returns a positive error code on failure, -1 in case of an
13454
 * internal error, 0 otherwise.
13455
 */
13456
static int
13457
xmlSchemaUnionWildcards(xmlSchemaParserCtxtPtr ctxt,
13458
          xmlSchemaWildcardPtr completeWild,
13459
          xmlSchemaWildcardPtr curWild)
13460
0
{
13461
0
    xmlSchemaWildcardNsPtr cur, curB, tmp;
13462
13463
    /*
13464
    * 1 If O1 and O2 are the same value, then that value must be the
13465
    * value.
13466
    */
13467
0
    if ((completeWild->any == curWild->any) &&
13468
0
  ((completeWild->nsSet == NULL) == (curWild->nsSet == NULL)) &&
13469
0
  ((completeWild->negNsSet == NULL) == (curWild->negNsSet == NULL))) {
13470
13471
0
  if ((completeWild->negNsSet == NULL) ||
13472
0
      (completeWild->negNsSet->value == curWild->negNsSet->value)) {
13473
13474
0
      if (completeWild->nsSet != NULL) {
13475
0
    int found = 0;
13476
13477
    /*
13478
    * Check equality of sets.
13479
    */
13480
0
    cur = completeWild->nsSet;
13481
0
    while (cur != NULL) {
13482
0
        found = 0;
13483
0
        curB = curWild->nsSet;
13484
0
        while (curB != NULL) {
13485
0
      if (cur->value == curB->value) {
13486
0
          found = 1;
13487
0
          break;
13488
0
      }
13489
0
      curB = curB->next;
13490
0
        }
13491
0
        if (!found)
13492
0
      break;
13493
0
        cur = cur->next;
13494
0
    }
13495
0
    if (found)
13496
0
        return(0);
13497
0
      } else
13498
0
    return(0);
13499
0
  }
13500
0
    }
13501
    /*
13502
    * 2 If either O1 or O2 is any, then any must be the value
13503
    */
13504
0
    if (completeWild->any != curWild->any) {
13505
0
  if (completeWild->any == 0) {
13506
0
      completeWild->any = 1;
13507
0
      if (completeWild->nsSet != NULL) {
13508
0
    xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
13509
0
    completeWild->nsSet = NULL;
13510
0
      }
13511
0
      if (completeWild->negNsSet != NULL) {
13512
0
    xmlFree(completeWild->negNsSet);
13513
0
    completeWild->negNsSet = NULL;
13514
0
      }
13515
0
  }
13516
0
  return (0);
13517
0
    }
13518
    /*
13519
    * 3 If both O1 and O2 are sets of (namespace names or `absent`),
13520
    * then the union of those sets must be the value.
13521
    */
13522
0
    if ((completeWild->nsSet != NULL) && (curWild->nsSet != NULL)) {
13523
0
  int found;
13524
0
  xmlSchemaWildcardNsPtr start;
13525
13526
0
  cur = curWild->nsSet;
13527
0
  start = completeWild->nsSet;
13528
0
  while (cur != NULL) {
13529
0
      found = 0;
13530
0
      curB = start;
13531
0
      while (curB != NULL) {
13532
0
    if (cur->value == curB->value) {
13533
0
        found = 1;
13534
0
        break;
13535
0
    }
13536
0
    curB = curB->next;
13537
0
      }
13538
0
      if (!found) {
13539
0
    tmp = xmlSchemaNewWildcardNsConstraint(ctxt);
13540
0
    if (tmp == NULL)
13541
0
        return (-1);
13542
0
    tmp->value = cur->value;
13543
0
    tmp->next = completeWild->nsSet;
13544
0
    completeWild->nsSet = tmp;
13545
0
      }
13546
0
      cur = cur->next;
13547
0
  }
13548
13549
0
  return(0);
13550
0
    }
13551
    /*
13552
    * 4 If the two are negations of different values (namespace names
13553
    * or `absent`), then a pair of not and `absent` must be the value.
13554
    */
13555
0
    if ((completeWild->negNsSet != NULL) &&
13556
0
  (curWild->negNsSet != NULL) &&
13557
0
  (completeWild->negNsSet->value != curWild->negNsSet->value)) {
13558
0
  completeWild->negNsSet->value = NULL;
13559
13560
0
  return(0);
13561
0
    }
13562
    /*
13563
     * 5.
13564
     */
13565
0
    if (((completeWild->negNsSet != NULL) &&
13566
0
  (completeWild->negNsSet->value != NULL) &&
13567
0
  (curWild->nsSet != NULL)) ||
13568
0
  ((curWild->negNsSet != NULL) &&
13569
0
  (curWild->negNsSet->value != NULL) &&
13570
0
  (completeWild->nsSet != NULL))) {
13571
13572
0
  int nsFound, absentFound = 0;
13573
13574
0
  if (completeWild->nsSet != NULL) {
13575
0
      cur = completeWild->nsSet;
13576
0
      curB = curWild->negNsSet;
13577
0
  } else {
13578
0
      cur = curWild->nsSet;
13579
0
      curB = completeWild->negNsSet;
13580
0
  }
13581
0
  nsFound = 0;
13582
0
  while (cur != NULL) {
13583
0
      if (cur->value == NULL)
13584
0
    absentFound = 1;
13585
0
      else if (cur->value == curB->value)
13586
0
    nsFound = 1;
13587
0
      if (nsFound && absentFound)
13588
0
    break;
13589
0
      cur = cur->next;
13590
0
  }
13591
13592
0
  if (nsFound && absentFound) {
13593
      /*
13594
      * 5.1 If the set S includes both the negated namespace
13595
      * name and `absent`, then any must be the value.
13596
      */
13597
0
      completeWild->any = 1;
13598
0
      if (completeWild->nsSet != NULL) {
13599
0
    xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
13600
0
    completeWild->nsSet = NULL;
13601
0
      }
13602
0
      if (completeWild->negNsSet != NULL) {
13603
0
    xmlFree(completeWild->negNsSet);
13604
0
    completeWild->negNsSet = NULL;
13605
0
      }
13606
0
  } else if (nsFound && (!absentFound)) {
13607
      /*
13608
      * 5.2 If the set S includes the negated namespace name
13609
      * but not `absent`, then a pair of not and `absent` must
13610
      * be the value.
13611
      */
13612
0
      if (completeWild->nsSet != NULL) {
13613
0
    xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
13614
0
    completeWild->nsSet = NULL;
13615
0
      }
13616
0
      if (completeWild->negNsSet == NULL) {
13617
0
    completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
13618
0
    if (completeWild->negNsSet == NULL)
13619
0
        return (-1);
13620
0
      }
13621
0
      completeWild->negNsSet->value = NULL;
13622
0
  } else if ((!nsFound) && absentFound) {
13623
      /*
13624
      * 5.3 If the set S includes `absent` but not the negated
13625
      * namespace name, then the union is not expressible.
13626
      */
13627
0
      xmlSchemaPErr(ctxt, completeWild->node,
13628
0
    XML_SCHEMAP_UNION_NOT_EXPRESSIBLE,
13629
0
    "The union of the wildcard is not expressible.\n",
13630
0
    NULL, NULL);
13631
0
      return(XML_SCHEMAP_UNION_NOT_EXPRESSIBLE);
13632
0
  } else if ((!nsFound) && (!absentFound)) {
13633
      /*
13634
      * 5.4 If the set S does not include either the negated namespace
13635
      * name or `absent`, then whichever of O1 or O2 is a pair of not
13636
      * and a namespace name must be the value.
13637
      */
13638
0
      if (completeWild->negNsSet == NULL) {
13639
0
    if (completeWild->nsSet != NULL) {
13640
0
        xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
13641
0
        completeWild->nsSet = NULL;
13642
0
    }
13643
0
    completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
13644
0
    if (completeWild->negNsSet == NULL)
13645
0
        return (-1);
13646
0
    completeWild->negNsSet->value = curWild->negNsSet->value;
13647
0
      }
13648
0
  }
13649
0
  return (0);
13650
0
    }
13651
    /*
13652
     * 6.
13653
     */
13654
0
    if (((completeWild->negNsSet != NULL) &&
13655
0
  (completeWild->negNsSet->value == NULL) &&
13656
0
  (curWild->nsSet != NULL)) ||
13657
0
  ((curWild->negNsSet != NULL) &&
13658
0
  (curWild->negNsSet->value == NULL) &&
13659
0
  (completeWild->nsSet != NULL))) {
13660
13661
0
  if (completeWild->nsSet != NULL) {
13662
0
      cur = completeWild->nsSet;
13663
0
  } else {
13664
0
      cur = curWild->nsSet;
13665
0
  }
13666
0
  while (cur != NULL) {
13667
0
      if (cur->value == NULL) {
13668
    /*
13669
    * 6.1 If the set S includes `absent`, then any must be the
13670
    * value.
13671
    */
13672
0
    completeWild->any = 1;
13673
0
    if (completeWild->nsSet != NULL) {
13674
0
        xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
13675
0
        completeWild->nsSet = NULL;
13676
0
    }
13677
0
    if (completeWild->negNsSet != NULL) {
13678
0
        xmlFree(completeWild->negNsSet);
13679
0
        completeWild->negNsSet = NULL;
13680
0
    }
13681
0
    return (0);
13682
0
      }
13683
0
      cur = cur->next;
13684
0
  }
13685
0
  if (completeWild->negNsSet == NULL) {
13686
      /*
13687
      * 6.2 If the set S does not include `absent`, then a pair of not
13688
      * and `absent` must be the value.
13689
      */
13690
0
      if (completeWild->nsSet != NULL) {
13691
0
    xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
13692
0
    completeWild->nsSet = NULL;
13693
0
      }
13694
0
      completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
13695
0
      if (completeWild->negNsSet == NULL)
13696
0
    return (-1);
13697
0
      completeWild->negNsSet->value = NULL;
13698
0
  }
13699
0
  return (0);
13700
0
    }
13701
0
    return (0);
13702
13703
0
}
13704
13705
/**
13706
 * xmlSchemaIntersectWildcards:
13707
 * @ctxt:  the schema parser context
13708
 * @completeWild:  the first wildcard
13709
 * @curWild: the second wildcard
13710
 *
13711
 * Intersects the namespace constraints of the given wildcards.
13712
 * @completeWild will hold the resulting intersection.
13713
 * Returns a positive error code on failure, -1 in case of an
13714
 * internal error, 0 otherwise.
13715
 */
13716
static int
13717
xmlSchemaIntersectWildcards(xmlSchemaParserCtxtPtr ctxt,
13718
          xmlSchemaWildcardPtr completeWild,
13719
          xmlSchemaWildcardPtr curWild)
13720
0
{
13721
0
    xmlSchemaWildcardNsPtr cur, curB, prev,  tmp;
13722
13723
    /*
13724
    * 1 If O1 and O2 are the same value, then that value must be the
13725
    * value.
13726
    */
13727
0
    if ((completeWild->any == curWild->any) &&
13728
0
  ((completeWild->nsSet == NULL) == (curWild->nsSet == NULL)) &&
13729
0
  ((completeWild->negNsSet == NULL) == (curWild->negNsSet == NULL))) {
13730
13731
0
  if ((completeWild->negNsSet == NULL) ||
13732
0
      (completeWild->negNsSet->value == curWild->negNsSet->value)) {
13733
13734
0
      if (completeWild->nsSet != NULL) {
13735
0
    int found = 0;
13736
13737
    /*
13738
    * Check equality of sets.
13739
    */
13740
0
    cur = completeWild->nsSet;
13741
0
    while (cur != NULL) {
13742
0
        found = 0;
13743
0
        curB = curWild->nsSet;
13744
0
        while (curB != NULL) {
13745
0
      if (cur->value == curB->value) {
13746
0
          found = 1;
13747
0
          break;
13748
0
      }
13749
0
      curB = curB->next;
13750
0
        }
13751
0
        if (!found)
13752
0
      break;
13753
0
        cur = cur->next;
13754
0
    }
13755
0
    if (found)
13756
0
        return(0);
13757
0
      } else
13758
0
    return(0);
13759
0
  }
13760
0
    }
13761
    /*
13762
    * 2 If either O1 or O2 is any, then the other must be the value.
13763
    */
13764
0
    if ((completeWild->any != curWild->any) && (completeWild->any)) {
13765
0
  if (xmlSchemaCloneWildcardNsConstraints(ctxt, completeWild, curWild) == -1)
13766
0
      return(-1);
13767
0
  return(0);
13768
0
    }
13769
    /*
13770
    * 3 If either O1 or O2 is a pair of not and a value (a namespace
13771
    * name or `absent`) and the other is a set of (namespace names or
13772
    * `absent`), then that set, minus the negated value if it was in
13773
    * the set, minus `absent` if it was in the set, must be the value.
13774
    */
13775
0
    if (((completeWild->negNsSet != NULL) && (curWild->nsSet != NULL)) ||
13776
0
  ((curWild->negNsSet != NULL) && (completeWild->nsSet != NULL))) {
13777
0
  const xmlChar *neg;
13778
13779
0
  if (completeWild->nsSet == NULL) {
13780
0
      neg = completeWild->negNsSet->value;
13781
0
      if (xmlSchemaCloneWildcardNsConstraints(ctxt, completeWild, curWild) == -1)
13782
0
    return(-1);
13783
0
  } else
13784
0
      neg = curWild->negNsSet->value;
13785
  /*
13786
  * Remove absent and negated.
13787
  */
13788
0
  prev = NULL;
13789
0
  cur = completeWild->nsSet;
13790
0
  while (cur != NULL) {
13791
0
      if (cur->value == NULL) {
13792
0
    if (prev == NULL)
13793
0
        completeWild->nsSet = cur->next;
13794
0
    else
13795
0
        prev->next = cur->next;
13796
0
    xmlFree(cur);
13797
0
    break;
13798
0
      }
13799
0
      prev = cur;
13800
0
      cur = cur->next;
13801
0
  }
13802
0
  if (neg != NULL) {
13803
0
      prev = NULL;
13804
0
      cur = completeWild->nsSet;
13805
0
      while (cur != NULL) {
13806
0
    if (cur->value == neg) {
13807
0
        if (prev == NULL)
13808
0
      completeWild->nsSet = cur->next;
13809
0
        else
13810
0
      prev->next = cur->next;
13811
0
        xmlFree(cur);
13812
0
        break;
13813
0
    }
13814
0
    prev = cur;
13815
0
    cur = cur->next;
13816
0
      }
13817
0
  }
13818
13819
0
  return(0);
13820
0
    }
13821
    /*
13822
    * 4 If both O1 and O2 are sets of (namespace names or `absent`),
13823
    * then the intersection of those sets must be the value.
13824
    */
13825
0
    if ((completeWild->nsSet != NULL) && (curWild->nsSet != NULL)) {
13826
0
  int found;
13827
13828
0
  cur = completeWild->nsSet;
13829
0
  prev = NULL;
13830
0
  while (cur != NULL) {
13831
0
      found = 0;
13832
0
      curB = curWild->nsSet;
13833
0
      while (curB != NULL) {
13834
0
    if (cur->value == curB->value) {
13835
0
        found = 1;
13836
0
        break;
13837
0
    }
13838
0
    curB = curB->next;
13839
0
      }
13840
0
      if (!found) {
13841
0
    if (prev == NULL)
13842
0
        completeWild->nsSet = cur->next;
13843
0
    else
13844
0
        prev->next = cur->next;
13845
0
    tmp = cur->next;
13846
0
    xmlFree(cur);
13847
0
    cur = tmp;
13848
0
    continue;
13849
0
      }
13850
0
      prev = cur;
13851
0
      cur = cur->next;
13852
0
  }
13853
13854
0
  return(0);
13855
0
    }
13856
    /* 5 If the two are negations of different namespace names,
13857
    * then the intersection is not expressible
13858
    */
13859
0
    if ((completeWild->negNsSet != NULL) &&
13860
0
  (curWild->negNsSet != NULL) &&
13861
0
  (completeWild->negNsSet->value != curWild->negNsSet->value) &&
13862
0
  (completeWild->negNsSet->value != NULL) &&
13863
0
  (curWild->negNsSet->value != NULL)) {
13864
13865
0
  xmlSchemaPErr(ctxt, completeWild->node, XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE,
13866
0
      "The intersection of the wildcard is not expressible.\n",
13867
0
      NULL, NULL);
13868
0
  return(XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE);
13869
0
    }
13870
    /*
13871
    * 6 If the one is a negation of a namespace name and the other
13872
    * is a negation of `absent`, then the one which is the negation
13873
    * of a namespace name must be the value.
13874
    */
13875
0
    if ((completeWild->negNsSet != NULL) && (curWild->negNsSet != NULL) &&
13876
0
  (completeWild->negNsSet->value != curWild->negNsSet->value) &&
13877
0
  (completeWild->negNsSet->value == NULL)) {
13878
0
  completeWild->negNsSet->value =  curWild->negNsSet->value;
13879
0
    }
13880
0
    return(0);
13881
0
}
13882
13883
/**
13884
 * xmlSchemaIsWildcardNsConstraintSubset:
13885
 * @ctxt:  the schema parser context
13886
 * @sub:  the first wildcard
13887
 * @super: the second wildcard
13888
 *
13889
 * Schema Component Constraint: Wildcard Subset (cos-ns-subset)
13890
 *
13891
 * Returns 0 if the namespace constraint of @sub is an intensional
13892
 * subset of @super, 1 otherwise.
13893
 */
13894
static int
13895
xmlSchemaCheckCOSNSSubset(xmlSchemaWildcardPtr sub,
13896
        xmlSchemaWildcardPtr super)
13897
0
{
13898
    /*
13899
    * 1 super must be any.
13900
    */
13901
0
    if (super->any)
13902
0
  return (0);
13903
    /*
13904
    * 2.1 sub must be a pair of not and a namespace name or `absent`.
13905
    * 2.2 super must be a pair of not and the same value.
13906
    */
13907
0
    if ((sub->negNsSet != NULL) &&
13908
0
  (super->negNsSet != NULL) &&
13909
0
  (sub->negNsSet->value == super->negNsSet->value))
13910
0
  return (0);
13911
    /*
13912
    * 3.1 sub must be a set whose members are either namespace names or `absent`.
13913
    */
13914
0
    if (sub->nsSet != NULL) {
13915
  /*
13916
  * 3.2.1 super must be the same set or a superset thereof.
13917
  */
13918
0
  if (super->nsSet != NULL) {
13919
0
      xmlSchemaWildcardNsPtr cur, curB;
13920
0
      int found = 0;
13921
13922
0
      cur = sub->nsSet;
13923
0
      while (cur != NULL) {
13924
0
    found = 0;
13925
0
    curB = super->nsSet;
13926
0
    while (curB != NULL) {
13927
0
        if (cur->value == curB->value) {
13928
0
      found = 1;
13929
0
      break;
13930
0
        }
13931
0
        curB = curB->next;
13932
0
    }
13933
0
    if (!found)
13934
0
        return (1);
13935
0
    cur = cur->next;
13936
0
      }
13937
0
      if (found)
13938
0
    return (0);
13939
0
  } else if (super->negNsSet != NULL) {
13940
0
      xmlSchemaWildcardNsPtr cur;
13941
      /*
13942
      * 3.2.2 super must be a pair of not and a namespace name or
13943
      * `absent` and that value must not be in sub's set.
13944
      */
13945
0
      cur = sub->nsSet;
13946
0
      while (cur != NULL) {
13947
0
    if (cur->value == super->negNsSet->value)
13948
0
        return (1);
13949
0
    cur = cur->next;
13950
0
      }
13951
0
      return (0);
13952
0
  }
13953
0
    }
13954
0
    return (1);
13955
0
}
13956
13957
static int
13958
xmlSchemaGetEffectiveValueConstraint(xmlSchemaAttributeUsePtr attruse,
13959
             int *fixed,
13960
             const xmlChar **value,
13961
             xmlSchemaValPtr *val)
13962
0
{
13963
0
    *fixed = 0;
13964
0
    *value = NULL;
13965
0
    if (val != 0)
13966
0
  *val = NULL;
13967
13968
0
    if (attruse->defValue != NULL) {
13969
0
  *value = attruse->defValue;
13970
0
  if (val != NULL)
13971
0
      *val = attruse->defVal;
13972
0
  if (attruse->flags & XML_SCHEMA_ATTR_USE_FIXED)
13973
0
      *fixed = 1;
13974
0
  return(1);
13975
0
    } else if ((attruse->attrDecl != NULL) &&
13976
0
  (attruse->attrDecl->defValue != NULL)) {
13977
0
  *value = attruse->attrDecl->defValue;
13978
0
  if (val != NULL)
13979
0
      *val = attruse->attrDecl->defVal;
13980
0
  if (attruse->attrDecl->flags & XML_SCHEMAS_ATTR_FIXED)
13981
0
      *fixed = 1;
13982
0
  return(1);
13983
0
    }
13984
0
    return(0);
13985
0
}
13986
/**
13987
 * xmlSchemaCheckCVCWildcardNamespace:
13988
 * @wild:  the wildcard
13989
 * @ns:  the namespace
13990
 *
13991
 * Validation Rule: Wildcard allows Namespace Name
13992
 * (cvc-wildcard-namespace)
13993
 *
13994
 * Returns 0 if the given namespace matches the wildcard,
13995
 * 1 otherwise and -1 on API errors.
13996
 */
13997
static int
13998
xmlSchemaCheckCVCWildcardNamespace(xmlSchemaWildcardPtr wild,
13999
           const xmlChar* ns)
14000
0
{
14001
0
    if (wild == NULL)
14002
0
  return(-1);
14003
14004
0
    if (wild->any)
14005
0
  return(0);
14006
0
    else if (wild->nsSet != NULL) {
14007
0
  xmlSchemaWildcardNsPtr cur;
14008
14009
0
  cur = wild->nsSet;
14010
0
  while (cur != NULL) {
14011
0
      if (xmlStrEqual(cur->value, ns))
14012
0
    return(0);
14013
0
      cur = cur->next;
14014
0
  }
14015
0
    } else if ((wild->negNsSet != NULL) && (ns != NULL) &&
14016
0
  (!xmlStrEqual(wild->negNsSet->value, ns)))
14017
0
  return(0);
14018
14019
0
    return(1);
14020
0
}
14021
14022
0
#define XML_SCHEMA_ACTION_DERIVE 0
14023
0
#define XML_SCHEMA_ACTION_REDEFINE 1
14024
14025
0
#define WXS_ACTION_STR(a) \
14026
0
((a) == XML_SCHEMA_ACTION_DERIVE) ? (const xmlChar *) "base" : (const xmlChar *) "redefined"
14027
14028
/*
14029
* Schema Component Constraint:
14030
*   Derivation Valid (Restriction, Complex)
14031
*   derivation-ok-restriction (2) - (4)
14032
*
14033
* ATTENTION:
14034
* In XML Schema 1.1 this will be:
14035
* Validation Rule:
14036
*     Checking complex type subsumption (practicalSubsumption) (1, 2 and 3)
14037
*
14038
*/
14039
static int
14040
xmlSchemaCheckDerivationOKRestriction2to4(xmlSchemaParserCtxtPtr pctxt,
14041
               int action,
14042
               xmlSchemaBasicItemPtr item,
14043
               xmlSchemaBasicItemPtr baseItem,
14044
               xmlSchemaItemListPtr uses,
14045
               xmlSchemaItemListPtr baseUses,
14046
               xmlSchemaWildcardPtr wild,
14047
               xmlSchemaWildcardPtr baseWild)
14048
0
{
14049
0
    xmlSchemaAttributeUsePtr cur = NULL, bcur;
14050
0
    int i, j, found; /* err = 0; */
14051
0
    const xmlChar *bEffValue;
14052
0
    int effFixed;
14053
14054
0
    if (uses != NULL) {
14055
0
  for (i = 0; i < uses->nbItems; i++) {
14056
0
      cur = uses->items[i];
14057
0
      found = 0;
14058
0
      if (baseUses == NULL)
14059
0
    goto not_found;
14060
0
      for (j = 0; j < baseUses->nbItems; j++) {
14061
0
    bcur = baseUses->items[j];
14062
0
    if ((WXS_ATTRUSE_DECL_NAME(cur) ==
14063
0
      WXS_ATTRUSE_DECL_NAME(bcur)) &&
14064
0
        (WXS_ATTRUSE_DECL_TNS(cur) ==
14065
0
      WXS_ATTRUSE_DECL_TNS(bcur)))
14066
0
    {
14067
        /*
14068
        * (2.1) "If there is an attribute use in the {attribute
14069
        * uses} of the {base type definition} (call this B) whose
14070
        * {attribute declaration} has the same {name} and {target
14071
        * namespace}, then  all of the following must be true:"
14072
        */
14073
0
        found = 1;
14074
14075
0
        if ((cur->occurs == XML_SCHEMAS_ATTR_USE_OPTIONAL) &&
14076
0
      (bcur->occurs == XML_SCHEMAS_ATTR_USE_REQUIRED))
14077
0
        {
14078
0
      xmlChar *str = NULL;
14079
      /*
14080
      * (2.1.1) "one of the following must be true:"
14081
      * (2.1.1.1) "B's {required} is false."
14082
      * (2.1.1.2) "R's {required} is true."
14083
      */
14084
0
      xmlSchemaPAttrUseErr4(pctxt,
14085
0
          XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_1,
14086
0
          WXS_ITEM_NODE(item), item, cur,
14087
0
          "The 'optional' attribute use is inconsistent "
14088
0
          "with the corresponding 'required' attribute use of "
14089
0
          "the %s %s",
14090
0
          WXS_ACTION_STR(action),
14091
0
          xmlSchemaGetComponentDesignation(&str, baseItem),
14092
0
          NULL, NULL);
14093
0
      FREE_AND_NULL(str);
14094
      /* err = pctxt->err; */
14095
0
        } else if (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt,
14096
0
      WXS_ATTRUSE_TYPEDEF(cur),
14097
0
      WXS_ATTRUSE_TYPEDEF(bcur), 0) != 0)
14098
0
        {
14099
0
      xmlChar *strA = NULL, *strB = NULL, *strC = NULL;
14100
14101
      /*
14102
      * SPEC (2.1.2) "R's {attribute declaration}'s
14103
      * {type definition} must be validly derived from
14104
      * B's {type definition} given the empty set as
14105
      * defined in Type Derivation OK (Simple) ($3.14.6)."
14106
      */
14107
0
      xmlSchemaPAttrUseErr4(pctxt,
14108
0
          XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_2,
14109
0
          WXS_ITEM_NODE(item), item, cur,
14110
0
          "The attribute declaration's %s "
14111
0
          "is not validly derived from "
14112
0
          "the corresponding %s of the "
14113
0
          "attribute declaration in the %s %s",
14114
0
          xmlSchemaGetComponentDesignation(&strA,
14115
0
        WXS_ATTRUSE_TYPEDEF(cur)),
14116
0
          xmlSchemaGetComponentDesignation(&strB,
14117
0
        WXS_ATTRUSE_TYPEDEF(bcur)),
14118
0
          WXS_ACTION_STR(action),
14119
0
          xmlSchemaGetComponentDesignation(&strC, baseItem));
14120
          /* xmlSchemaGetComponentDesignation(&str, baseItem), */
14121
0
      FREE_AND_NULL(strA);
14122
0
      FREE_AND_NULL(strB);
14123
0
      FREE_AND_NULL(strC);
14124
      /* err = pctxt->err; */
14125
0
        } else {
14126
      /*
14127
      * 2.1.3 [Definition:]  Let the effective value
14128
      * constraint of an attribute use be its {value
14129
      * constraint}, if present, otherwise its {attribute
14130
      * declaration}'s {value constraint} .
14131
      */
14132
0
      xmlSchemaGetEffectiveValueConstraint(bcur,
14133
0
          &effFixed, &bEffValue, NULL);
14134
      /*
14135
      * 2.1.3 ... one of the following must be true
14136
      *
14137
      * 2.1.3.1 B's `effective value constraint` is
14138
      * `absent` or default.
14139
      */
14140
0
      if ((bEffValue != NULL) &&
14141
0
          (effFixed == 1)) {
14142
0
          const xmlChar *rEffValue = NULL;
14143
14144
0
          xmlSchemaGetEffectiveValueConstraint(bcur,
14145
0
        &effFixed, &rEffValue, NULL);
14146
          /*
14147
          * 2.1.3.2 R's `effective value constraint` is
14148
          * fixed with the same string as B's.
14149
          * MAYBE TODO: Compare the computed values.
14150
          *       Hmm, it says "same string" so
14151
          *       string-equality might really be sufficient.
14152
          */
14153
0
          if ((effFixed == 0) ||
14154
0
        (! WXS_ARE_DEFAULT_STR_EQUAL(rEffValue, bEffValue)))
14155
0
          {
14156
0
        xmlChar *str = NULL;
14157
14158
0
        xmlSchemaPAttrUseErr4(pctxt,
14159
0
            XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_3,
14160
0
            WXS_ITEM_NODE(item), item, cur,
14161
0
            "The effective value constraint of the "
14162
0
            "attribute use is inconsistent with "
14163
0
            "its correspondent in the %s %s",
14164
0
            WXS_ACTION_STR(action),
14165
0
            xmlSchemaGetComponentDesignation(&str,
14166
0
          baseItem),
14167
0
            NULL, NULL);
14168
0
        FREE_AND_NULL(str);
14169
        /* err = pctxt->err; */
14170
0
          }
14171
0
      }
14172
0
        }
14173
0
        break;
14174
0
    }
14175
0
      }
14176
0
not_found:
14177
0
      if (!found) {
14178
    /*
14179
    * (2.2) "otherwise the {base type definition} must have an
14180
    * {attribute wildcard} and the {target namespace} of the
14181
    * R's {attribute declaration} must be `valid` with respect
14182
    * to that wildcard, as defined in Wildcard allows Namespace
14183
    * Name ($3.10.4)."
14184
    */
14185
0
    if ((baseWild == NULL) ||
14186
0
        (xmlSchemaCheckCVCWildcardNamespace(baseWild,
14187
0
        (WXS_ATTRUSE_DECL(cur))->targetNamespace) != 0))
14188
0
    {
14189
0
        xmlChar *str = NULL;
14190
14191
0
        xmlSchemaPAttrUseErr4(pctxt,
14192
0
      XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_2,
14193
0
      WXS_ITEM_NODE(item), item, cur,
14194
0
      "Neither a matching attribute use, "
14195
0
      "nor a matching wildcard exists in the %s %s",
14196
0
      WXS_ACTION_STR(action),
14197
0
      xmlSchemaGetComponentDesignation(&str, baseItem),
14198
0
      NULL, NULL);
14199
0
        FREE_AND_NULL(str);
14200
        /* err = pctxt->err; */
14201
0
    }
14202
0
      }
14203
0
  }
14204
0
    }
14205
    /*
14206
    * SPEC derivation-ok-restriction (3):
14207
    * (3) "For each attribute use in the {attribute uses} of the {base type
14208
    * definition} whose {required} is true, there must be an attribute
14209
    * use with an {attribute declaration} with the same {name} and
14210
    * {target namespace} as its {attribute declaration} in the {attribute
14211
    * uses} of the complex type definition itself whose {required} is true.
14212
    */
14213
0
    if (baseUses != NULL) {
14214
0
  for (j = 0; j < baseUses->nbItems; j++) {
14215
0
      bcur = baseUses->items[j];
14216
0
      if (bcur->occurs != XML_SCHEMAS_ATTR_USE_REQUIRED)
14217
0
    continue;
14218
0
      found = 0;
14219
0
      if (uses != NULL) {
14220
0
    for (i = 0; i < uses->nbItems; i++) {
14221
0
        cur = uses->items[i];
14222
0
        if ((WXS_ATTRUSE_DECL_NAME(cur) ==
14223
0
      WXS_ATTRUSE_DECL_NAME(bcur)) &&
14224
0
      (WXS_ATTRUSE_DECL_TNS(cur) ==
14225
0
      WXS_ATTRUSE_DECL_TNS(bcur))) {
14226
0
      found = 1;
14227
0
      break;
14228
0
        }
14229
0
    }
14230
0
      }
14231
0
      if (!found) {
14232
0
    xmlChar *strA = NULL, *strB = NULL;
14233
14234
0
    xmlSchemaCustomErr4(ACTXT_CAST pctxt,
14235
0
        XML_SCHEMAP_DERIVATION_OK_RESTRICTION_3,
14236
0
        NULL, item,
14237
0
        "A matching attribute use for the "
14238
0
        "'required' %s of the %s %s is missing",
14239
0
        xmlSchemaGetComponentDesignation(&strA, bcur),
14240
0
        WXS_ACTION_STR(action),
14241
0
        xmlSchemaGetComponentDesignation(&strB, baseItem),
14242
0
        NULL);
14243
0
    FREE_AND_NULL(strA);
14244
0
    FREE_AND_NULL(strB);
14245
0
      }
14246
0
  }
14247
0
    }
14248
    /*
14249
    * derivation-ok-restriction (4)
14250
    */
14251
0
    if (wild != NULL) {
14252
  /*
14253
  * (4) "If there is an {attribute wildcard}, all of the
14254
  * following must be true:"
14255
  */
14256
0
  if (baseWild == NULL) {
14257
0
      xmlChar *str = NULL;
14258
14259
      /*
14260
      * (4.1) "The {base type definition} must also have one."
14261
      */
14262
0
      xmlSchemaCustomErr4(ACTXT_CAST pctxt,
14263
0
    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_1,
14264
0
    NULL, item,
14265
0
    "The %s has an attribute wildcard, "
14266
0
    "but the %s %s '%s' does not have one",
14267
0
    WXS_ITEM_TYPE_NAME(item),
14268
0
    WXS_ACTION_STR(action),
14269
0
    WXS_ITEM_TYPE_NAME(baseItem),
14270
0
    xmlSchemaGetComponentQName(&str, baseItem));
14271
0
      FREE_AND_NULL(str);
14272
0
      return(pctxt->err);
14273
0
  } else if ((baseWild->any == 0) &&
14274
0
    xmlSchemaCheckCOSNSSubset(wild, baseWild))
14275
0
  {
14276
0
      xmlChar *str = NULL;
14277
      /*
14278
      * (4.2) "The complex type definition's {attribute wildcard}'s
14279
      * {namespace constraint} must be a subset of the {base type
14280
      * definition}'s {attribute wildcard}'s {namespace constraint},
14281
      * as defined by Wildcard Subset ($3.10.6)."
14282
      */
14283
0
      xmlSchemaCustomErr4(ACTXT_CAST pctxt,
14284
0
    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_2,
14285
0
    NULL, item,
14286
0
    "The attribute wildcard is not a valid "
14287
0
    "subset of the wildcard in the %s %s '%s'",
14288
0
    WXS_ACTION_STR(action),
14289
0
    WXS_ITEM_TYPE_NAME(baseItem),
14290
0
    xmlSchemaGetComponentQName(&str, baseItem),
14291
0
    NULL);
14292
0
      FREE_AND_NULL(str);
14293
0
      return(pctxt->err);
14294
0
  }
14295
  /* 4.3 Unless the {base type definition} is the `ur-type
14296
  * definition`, the complex type definition's {attribute
14297
  * wildcard}'s {process contents} must be identical to or
14298
  * stronger than the {base type definition}'s {attribute
14299
  * wildcard}'s {process contents}, where strict is stronger
14300
  * than lax is stronger than skip.
14301
  */
14302
0
  if ((! WXS_IS_ANYTYPE(baseItem)) &&
14303
0
      (wild->processContents < baseWild->processContents)) {
14304
0
      xmlChar *str = NULL;
14305
0
      xmlSchemaCustomErr4(ACTXT_CAST pctxt,
14306
0
    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_3,
14307
0
    NULL, baseItem,
14308
0
    "The {process contents} of the attribute wildcard is "
14309
0
    "weaker than the one in the %s %s '%s'",
14310
0
    WXS_ACTION_STR(action),
14311
0
    WXS_ITEM_TYPE_NAME(baseItem),
14312
0
    xmlSchemaGetComponentQName(&str, baseItem),
14313
0
    NULL);
14314
0
      FREE_AND_NULL(str)
14315
0
    return(pctxt->err);
14316
0
  }
14317
0
    }
14318
0
    return(0);
14319
0
}
14320
14321
14322
static int
14323
xmlSchemaExpandAttributeGroupRefs(xmlSchemaParserCtxtPtr pctxt,
14324
          xmlSchemaBasicItemPtr item,
14325
          xmlSchemaWildcardPtr *completeWild,
14326
          xmlSchemaItemListPtr list,
14327
          xmlSchemaItemListPtr prohibs);
14328
/**
14329
 * xmlSchemaFixupTypeAttributeUses:
14330
 * @ctxt:  the schema parser context
14331
 * @type:  the complex type definition
14332
 *
14333
 *
14334
 * Builds the wildcard and the attribute uses on the given complex type.
14335
 * Returns -1 if an internal error occurs, 0 otherwise.
14336
 *
14337
 * ATTENTION TODO: Experimentally this uses pointer comparisons for
14338
 * strings, so recheck this if we start to hardcode some schemata, since
14339
 * they might not be in the same dict.
14340
 * NOTE: It is allowed to "extend" the xs:anyType type.
14341
 */
14342
static int
14343
xmlSchemaFixupTypeAttributeUses(xmlSchemaParserCtxtPtr pctxt,
14344
          xmlSchemaTypePtr type)
14345
0
{
14346
0
    xmlSchemaTypePtr baseType = NULL;
14347
0
    xmlSchemaAttributeUsePtr use;
14348
0
    xmlSchemaItemListPtr uses, baseUses, prohibs = NULL;
14349
14350
0
    if (type->baseType == NULL) {
14351
0
  PERROR_INT("xmlSchemaFixupTypeAttributeUses",
14352
0
      "no base type");
14353
0
        return (-1);
14354
0
    }
14355
0
    baseType = type->baseType;
14356
0
    if (WXS_IS_TYPE_NOT_FIXED(baseType))
14357
0
  if (xmlSchemaTypeFixup(baseType, ACTXT_CAST pctxt) == -1)
14358
0
      return(-1);
14359
14360
0
    uses = type->attrUses;
14361
0
    baseUses = baseType->attrUses;
14362
    /*
14363
    * Expand attribute group references. And build the 'complete'
14364
    * wildcard, i.e. intersect multiple wildcards.
14365
    * Move attribute prohibitions into a separate list.
14366
    */
14367
0
    if (uses != NULL) {
14368
0
  if (WXS_IS_RESTRICTION(type)) {
14369
      /*
14370
      * This one will transfer all attr. prohibitions
14371
      * into pctxt->attrProhibs.
14372
      */
14373
0
      if (xmlSchemaExpandAttributeGroupRefs(pctxt,
14374
0
    WXS_BASIC_CAST type, &(type->attributeWildcard), uses,
14375
0
    pctxt->attrProhibs) == -1)
14376
0
      {
14377
0
    PERROR_INT("xmlSchemaFixupTypeAttributeUses",
14378
0
    "failed to expand attributes");
14379
0
                return(-1);
14380
0
      }
14381
0
      if (pctxt->attrProhibs->nbItems != 0)
14382
0
    prohibs = pctxt->attrProhibs;
14383
0
  } else {
14384
0
      if (xmlSchemaExpandAttributeGroupRefs(pctxt,
14385
0
    WXS_BASIC_CAST type, &(type->attributeWildcard), uses,
14386
0
    NULL) == -1)
14387
0
      {
14388
0
    PERROR_INT("xmlSchemaFixupTypeAttributeUses",
14389
0
    "failed to expand attributes");
14390
0
                return(-1);
14391
0
      }
14392
0
  }
14393
0
    }
14394
    /*
14395
    * Inherit the attribute uses of the base type.
14396
    */
14397
0
    if (baseUses != NULL) {
14398
0
  int i, j;
14399
0
  xmlSchemaAttributeUseProhibPtr pro;
14400
14401
0
  if (WXS_IS_RESTRICTION(type)) {
14402
0
      int usesCount;
14403
0
      xmlSchemaAttributeUsePtr tmp;
14404
14405
0
      if (uses != NULL)
14406
0
    usesCount = uses->nbItems;
14407
0
      else
14408
0
    usesCount = 0;
14409
14410
      /* Restriction. */
14411
0
      for (i = 0; i < baseUses->nbItems; i++) {
14412
0
    use = baseUses->items[i];
14413
0
    if (prohibs) {
14414
        /*
14415
        * Filter out prohibited uses.
14416
        */
14417
0
        for (j = 0; j < prohibs->nbItems; j++) {
14418
0
      pro = prohibs->items[j];
14419
0
      if ((WXS_ATTRUSE_DECL_NAME(use) == pro->name) &&
14420
0
          (WXS_ATTRUSE_DECL_TNS(use) ==
14421
0
        pro->targetNamespace))
14422
0
      {
14423
0
          goto inherit_next;
14424
0
      }
14425
0
        }
14426
0
    }
14427
0
    if (usesCount) {
14428
        /*
14429
        * Filter out existing uses.
14430
        */
14431
0
        for (j = 0; j < usesCount; j++) {
14432
0
      tmp = uses->items[j];
14433
0
      if ((WXS_ATTRUSE_DECL_NAME(use) ==
14434
0
        WXS_ATTRUSE_DECL_NAME(tmp)) &&
14435
0
          (WXS_ATTRUSE_DECL_TNS(use) ==
14436
0
        WXS_ATTRUSE_DECL_TNS(tmp)))
14437
0
      {
14438
0
          goto inherit_next;
14439
0
      }
14440
0
        }
14441
0
    }
14442
0
    if (uses == NULL) {
14443
0
        type->attrUses = xmlSchemaItemListCreate();
14444
0
        if (type->attrUses == NULL)
14445
0
      goto exit_failure;
14446
0
        uses = type->attrUses;
14447
0
    }
14448
0
    xmlSchemaItemListAddSize(uses, 2, use);
14449
0
inherit_next: {}
14450
0
      }
14451
0
  } else {
14452
      /* Extension. */
14453
0
      for (i = 0; i < baseUses->nbItems; i++) {
14454
0
    use = baseUses->items[i];
14455
0
    if (uses == NULL) {
14456
0
        type->attrUses = xmlSchemaItemListCreate();
14457
0
        if (type->attrUses == NULL)
14458
0
      goto exit_failure;
14459
0
        uses = type->attrUses;
14460
0
    }
14461
0
    xmlSchemaItemListAddSize(uses, baseUses->nbItems, use);
14462
0
      }
14463
0
  }
14464
0
    }
14465
    /*
14466
    * Shrink attr. uses.
14467
    */
14468
0
    if (uses) {
14469
0
  if (uses->nbItems == 0) {
14470
0
      xmlSchemaItemListFree(uses);
14471
0
      type->attrUses = NULL;
14472
0
  }
14473
  /*
14474
  * TODO: We could shrink the size of the array
14475
  * to fit the actual number of items.
14476
  */
14477
0
    }
14478
    /*
14479
    * Compute the complete wildcard.
14480
    */
14481
0
    if (WXS_IS_EXTENSION(type)) {
14482
0
  if (baseType->attributeWildcard != NULL) {
14483
      /*
14484
      * (3.2.2.1) "If the `base wildcard` is non-`absent`, then
14485
      * the appropriate case among the following:"
14486
      */
14487
0
      if (type->attributeWildcard != NULL) {
14488
    /*
14489
    * Union the complete wildcard with the base wildcard.
14490
    * SPEC {attribute wildcard}
14491
    * (3.2.2.1.2) "otherwise a wildcard whose {process contents}
14492
    * and {annotation} are those of the `complete wildcard`,
14493
    * and whose {namespace constraint} is the intensional union
14494
    * of the {namespace constraint} of the `complete wildcard`
14495
    * and of the `base wildcard`, as defined in Attribute
14496
    * Wildcard Union ($3.10.6)."
14497
    */
14498
0
    if (xmlSchemaUnionWildcards(pctxt, type->attributeWildcard,
14499
0
        baseType->attributeWildcard) == -1)
14500
0
        goto exit_failure;
14501
0
      } else {
14502
    /*
14503
    * (3.2.2.1.1) "If the `complete wildcard` is `absent`,
14504
    * then the `base wildcard`."
14505
    */
14506
0
    type->attributeWildcard = baseType->attributeWildcard;
14507
0
      }
14508
0
  } else {
14509
      /*
14510
      * (3.2.2.2) "otherwise (the `base wildcard` is `absent`) the
14511
      * `complete wildcard`"
14512
      * NOOP
14513
      */
14514
0
  }
14515
0
    } else {
14516
  /*
14517
  * SPEC {attribute wildcard}
14518
  * (3.1) "If the <restriction> alternative is chosen, then the
14519
  * `complete wildcard`;"
14520
  * NOOP
14521
  */
14522
0
    }
14523
14524
0
    return (0);
14525
14526
0
exit_failure:
14527
0
    return(-1);
14528
0
}
14529
14530
/**
14531
 * xmlSchemaTypeFinalContains:
14532
 * @schema:  the schema
14533
 * @type:  the type definition
14534
 * @final: the final
14535
 *
14536
 * Evaluates if a type definition contains the given "final".
14537
 * This does take "finalDefault" into account as well.
14538
 *
14539
 * Returns 1 if the type does contain the given "final",
14540
 * 0 otherwise.
14541
 */
14542
static int
14543
xmlSchemaTypeFinalContains(xmlSchemaTypePtr type, int final)
14544
0
{
14545
0
    if (type == NULL)
14546
0
  return (0);
14547
0
    if (type->flags & final)
14548
0
  return (1);
14549
0
    else
14550
0
  return (0);
14551
0
}
14552
14553
/**
14554
 * xmlSchemaGetUnionSimpleTypeMemberTypes:
14555
 * @type:  the Union Simple Type
14556
 *
14557
 * Returns a list of member types of @type if existing,
14558
 * returns NULL otherwise.
14559
 */
14560
static xmlSchemaTypeLinkPtr
14561
xmlSchemaGetUnionSimpleTypeMemberTypes(xmlSchemaTypePtr type)
14562
0
{
14563
0
    while ((type != NULL) && (type->type == XML_SCHEMA_TYPE_SIMPLE)) {
14564
0
  if (type->memberTypes != NULL)
14565
0
      return (type->memberTypes);
14566
0
  else
14567
0
      type = type->baseType;
14568
0
    }
14569
0
    return (NULL);
14570
0
}
14571
14572
#if 0
14573
/**
14574
 * xmlSchemaGetParticleTotalRangeMin:
14575
 * @particle: the particle
14576
 *
14577
 * Schema Component Constraint: Effective Total Range
14578
 * (all and sequence) + (choice)
14579
 *
14580
 * Returns the minimum Effective Total Range.
14581
 */
14582
static int
14583
xmlSchemaGetParticleTotalRangeMin(xmlSchemaParticlePtr particle)
14584
{
14585
    if ((particle->children == NULL) ||
14586
  (particle->minOccurs == 0))
14587
  return (0);
14588
    if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) {
14589
  int min = -1, cur;
14590
  xmlSchemaParticlePtr part =
14591
      (xmlSchemaParticlePtr) particle->children->children;
14592
14593
  if (part == NULL)
14594
      return (0);
14595
  while (part != NULL) {
14596
      if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
14597
    (part->children->type == XML_SCHEMA_TYPE_ANY))
14598
    cur = part->minOccurs;
14599
      else
14600
    cur = xmlSchemaGetParticleTotalRangeMin(part);
14601
      if (cur == 0)
14602
    return (0);
14603
      if ((min > cur) || (min == -1))
14604
    min = cur;
14605
      part = (xmlSchemaParticlePtr) part->next;
14606
  }
14607
  return (particle->minOccurs * min);
14608
    } else {
14609
  /* <all> and <sequence> */
14610
  int sum = 0;
14611
  xmlSchemaParticlePtr part =
14612
      (xmlSchemaParticlePtr) particle->children->children;
14613
14614
  if (part == NULL)
14615
      return (0);
14616
  do {
14617
      if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
14618
    (part->children->type == XML_SCHEMA_TYPE_ANY))
14619
    sum += part->minOccurs;
14620
      else
14621
    sum += xmlSchemaGetParticleTotalRangeMin(part);
14622
      part = (xmlSchemaParticlePtr) part->next;
14623
  } while (part != NULL);
14624
  return (particle->minOccurs * sum);
14625
    }
14626
}
14627
14628
/**
14629
 * xmlSchemaGetParticleTotalRangeMax:
14630
 * @particle: the particle
14631
 *
14632
 * Schema Component Constraint: Effective Total Range
14633
 * (all and sequence) + (choice)
14634
 *
14635
 * Returns the maximum Effective Total Range.
14636
 */
14637
static int
14638
xmlSchemaGetParticleTotalRangeMax(xmlSchemaParticlePtr particle)
14639
{
14640
    if ((particle->children == NULL) ||
14641
  (particle->children->children == NULL))
14642
  return (0);
14643
    if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) {
14644
  int max = -1, cur;
14645
  xmlSchemaParticlePtr part =
14646
      (xmlSchemaParticlePtr) particle->children->children;
14647
14648
  for (; part != NULL; part = (xmlSchemaParticlePtr) part->next) {
14649
      if (part->children == NULL)
14650
    continue;
14651
      if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
14652
    (part->children->type == XML_SCHEMA_TYPE_ANY))
14653
    cur = part->maxOccurs;
14654
      else
14655
    cur = xmlSchemaGetParticleTotalRangeMax(part);
14656
      if (cur == UNBOUNDED)
14657
    return (UNBOUNDED);
14658
      if ((max < cur) || (max == -1))
14659
    max = cur;
14660
  }
14661
  /* TODO: Handle overflows? */
14662
  return (particle->maxOccurs * max);
14663
    } else {
14664
  /* <all> and <sequence> */
14665
  int sum = 0, cur;
14666
  xmlSchemaParticlePtr part =
14667
      (xmlSchemaParticlePtr) particle->children->children;
14668
14669
  for (; part != NULL; part = (xmlSchemaParticlePtr) part->next) {
14670
      if (part->children == NULL)
14671
    continue;
14672
      if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
14673
    (part->children->type == XML_SCHEMA_TYPE_ANY))
14674
    cur = part->maxOccurs;
14675
      else
14676
    cur = xmlSchemaGetParticleTotalRangeMax(part);
14677
      if (cur == UNBOUNDED)
14678
    return (UNBOUNDED);
14679
      if ((cur > 0) && (particle->maxOccurs == UNBOUNDED))
14680
    return (UNBOUNDED);
14681
      sum += cur;
14682
  }
14683
  /* TODO: Handle overflows? */
14684
  return (particle->maxOccurs * sum);
14685
    }
14686
}
14687
#endif
14688
14689
/**
14690
 * xmlSchemaGetParticleEmptiable:
14691
 * @particle: the particle
14692
 *
14693
 * Returns 1 if emptiable, 0 otherwise.
14694
 */
14695
static int
14696
xmlSchemaGetParticleEmptiable(xmlSchemaParticlePtr particle)
14697
0
{
14698
0
    xmlSchemaParticlePtr part;
14699
0
    int emptiable;
14700
14701
0
    if ((particle->children == NULL) || (particle->minOccurs == 0))
14702
0
  return (1);
14703
14704
0
    part = (xmlSchemaParticlePtr) particle->children->children;
14705
0
    if (part == NULL)
14706
0
        return (1);
14707
14708
0
    while (part != NULL) {
14709
0
        if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
14710
0
            (part->children->type == XML_SCHEMA_TYPE_ANY))
14711
0
            emptiable = (part->minOccurs == 0);
14712
0
        else
14713
0
            emptiable = xmlSchemaGetParticleEmptiable(part);
14714
0
        if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) {
14715
0
            if (emptiable)
14716
0
                return (1);
14717
0
        } else {
14718
      /* <all> and <sequence> */
14719
0
            if (!emptiable)
14720
0
                return (0);
14721
0
        }
14722
0
        part = (xmlSchemaParticlePtr) part->next;
14723
0
    }
14724
14725
0
    if (particle->children->type == XML_SCHEMA_TYPE_CHOICE)
14726
0
        return (0);
14727
0
    else
14728
0
        return (1);
14729
0
}
14730
14731
/**
14732
 * xmlSchemaIsParticleEmptiable:
14733
 * @particle: the particle
14734
 *
14735
 * Schema Component Constraint: Particle Emptiable
14736
 * Checks whether the given particle is emptiable.
14737
 *
14738
 * Returns 1 if emptiable, 0 otherwise.
14739
 */
14740
static int
14741
xmlSchemaIsParticleEmptiable(xmlSchemaParticlePtr particle)
14742
0
{
14743
    /*
14744
    * SPEC (1) "Its {min occurs} is 0."
14745
    */
14746
0
    if ((particle == NULL) || (particle->minOccurs == 0) ||
14747
0
  (particle->children == NULL))
14748
0
  return (1);
14749
    /*
14750
    * SPEC (2) "Its {term} is a group and the minimum part of the
14751
    * effective total range of that group, [...] is 0."
14752
    */
14753
0
    if (WXS_IS_MODEL_GROUP(particle->children))
14754
0
  return (xmlSchemaGetParticleEmptiable(particle));
14755
0
    return (0);
14756
0
}
14757
14758
/**
14759
 * xmlSchemaCheckCOSSTDerivedOK:
14760
 * @actxt: a context
14761
 * @type:  the derived simple type definition
14762
 * @baseType:  the base type definition
14763
 * @subset: the subset of ('restriction', etc.)
14764
 *
14765
 * Schema Component Constraint:
14766
 * Type Derivation OK (Simple) (cos-st-derived-OK)
14767
 *
14768
 * Checks whether @type can be validly
14769
 * derived from @baseType.
14770
 *
14771
 * Returns 0 on success, an positive error code otherwise.
14772
 */
14773
static int
14774
xmlSchemaCheckCOSSTDerivedOK(xmlSchemaAbstractCtxtPtr actxt,
14775
           xmlSchemaTypePtr type,
14776
           xmlSchemaTypePtr baseType,
14777
           int subset)
14778
0
{
14779
    /*
14780
    * 1 They are the same type definition.
14781
    * TODO: The identity check might have to be more complex than this.
14782
    */
14783
0
    if (type == baseType)
14784
0
  return (0);
14785
    /*
14786
    * 2.1 restriction is not in the subset, or in the {final}
14787
    * of its own {base type definition};
14788
    *
14789
    * NOTE that this will be used also via "xsi:type".
14790
    *
14791
    * TODO: Revise this, it looks strange. How can the "type"
14792
    * not be fixed or *in* fixing?
14793
    */
14794
0
    if (WXS_IS_TYPE_NOT_FIXED(type))
14795
0
  if (xmlSchemaTypeFixup(type, actxt) == -1)
14796
0
      return(-1);
14797
0
    if (WXS_IS_TYPE_NOT_FIXED(baseType))
14798
0
  if (xmlSchemaTypeFixup(baseType, actxt) == -1)
14799
0
      return(-1);
14800
0
    if ((subset & SUBSET_RESTRICTION) ||
14801
0
  (xmlSchemaTypeFinalContains(type->baseType,
14802
0
      XML_SCHEMAS_TYPE_FINAL_RESTRICTION))) {
14803
0
  return (XML_SCHEMAP_COS_ST_DERIVED_OK_2_1);
14804
0
    }
14805
    /* 2.2 */
14806
0
    if (type->baseType == baseType) {
14807
  /*
14808
  * 2.2.1 D's `base type definition` is B.
14809
  */
14810
0
  return (0);
14811
0
    }
14812
    /*
14813
    * 2.2.2 D's `base type definition` is not the `ur-type definition`
14814
    * and is validly derived from B given the subset, as defined by this
14815
    * constraint.
14816
    */
14817
0
    if ((! WXS_IS_ANYTYPE(type->baseType)) &&
14818
0
  (xmlSchemaCheckCOSSTDerivedOK(actxt, type->baseType,
14819
0
      baseType, subset) == 0)) {
14820
0
  return (0);
14821
0
    }
14822
    /*
14823
    * 2.2.3 D's {variety} is list or union and B is the `simple ur-type
14824
    * definition`.
14825
    */
14826
0
    if (WXS_IS_ANY_SIMPLE_TYPE(baseType) &&
14827
0
  (WXS_IS_LIST(type) || WXS_IS_UNION(type))) {
14828
0
  return (0);
14829
0
    }
14830
    /*
14831
    * 2.2.4 B's {variety} is union and D is validly derived from a type
14832
    * definition in B's {member type definitions} given the subset, as
14833
    * defined by this constraint.
14834
    *
14835
    * NOTE: This seems not to involve built-in types, since there is no
14836
    * built-in Union Simple Type.
14837
    */
14838
0
    if (WXS_IS_UNION(baseType)) {
14839
0
  xmlSchemaTypeLinkPtr cur;
14840
14841
0
  cur = baseType->memberTypes;
14842
0
  while (cur != NULL) {
14843
0
      if (WXS_IS_TYPE_NOT_FIXED(cur->type))
14844
0
    if (xmlSchemaTypeFixup(cur->type, actxt) == -1)
14845
0
        return(-1);
14846
0
      if (xmlSchemaCheckCOSSTDerivedOK(actxt,
14847
0
        type, cur->type, subset) == 0)
14848
0
      {
14849
    /*
14850
    * It just has to be validly derived from at least one
14851
    * member-type.
14852
    */
14853
0
    return (0);
14854
0
      }
14855
0
      cur = cur->next;
14856
0
  }
14857
0
    }
14858
0
    return (XML_SCHEMAP_COS_ST_DERIVED_OK_2_2);
14859
0
}
14860
14861
/**
14862
 * xmlSchemaCheckTypeDefCircularInternal:
14863
 * @pctxt:  the schema parser context
14864
 * @ctxtType:  the type definition
14865
 * @ancestor: an ancestor of @ctxtType
14866
 *
14867
 * Checks st-props-correct (2) + ct-props-correct (3).
14868
 * Circular type definitions are not allowed.
14869
 *
14870
 * Returns XML_SCHEMAP_ST_PROPS_CORRECT_2 if the given type is
14871
 * circular, 0 otherwise.
14872
 */
14873
static int
14874
xmlSchemaCheckTypeDefCircularInternal(xmlSchemaParserCtxtPtr pctxt,
14875
         xmlSchemaTypePtr ctxtType,
14876
         xmlSchemaTypePtr ancestor)
14877
0
{
14878
0
    int ret;
14879
14880
0
    if ((ancestor == NULL) || (ancestor->type == XML_SCHEMA_TYPE_BASIC))
14881
0
  return (0);
14882
14883
0
    if (ctxtType == ancestor) {
14884
0
  xmlSchemaPCustomErr(pctxt,
14885
0
      XML_SCHEMAP_ST_PROPS_CORRECT_2,
14886
0
      WXS_BASIC_CAST ctxtType, WXS_ITEM_NODE(ctxtType),
14887
0
      "The definition is circular", NULL);
14888
0
  return (XML_SCHEMAP_ST_PROPS_CORRECT_2);
14889
0
    }
14890
0
    if (ancestor->flags & XML_SCHEMAS_TYPE_MARKED) {
14891
  /*
14892
  * Avoid infinite recursion on circular types not yet checked.
14893
  */
14894
0
  return (0);
14895
0
    }
14896
0
    ancestor->flags |= XML_SCHEMAS_TYPE_MARKED;
14897
0
    ret = xmlSchemaCheckTypeDefCircularInternal(pctxt, ctxtType,
14898
0
  ancestor->baseType);
14899
0
    ancestor->flags ^= XML_SCHEMAS_TYPE_MARKED;
14900
0
    return (ret);
14901
0
}
14902
14903
/**
14904
 * xmlSchemaCheckTypeDefCircular:
14905
 * @item:  the complex/simple type definition
14906
 * @ctxt:  the parser context
14907
 * @name:  the name
14908
 *
14909
 * Checks for circular type definitions.
14910
 */
14911
static void
14912
xmlSchemaCheckTypeDefCircular(xmlSchemaTypePtr item,
14913
            xmlSchemaParserCtxtPtr ctxt)
14914
0
{
14915
0
    if ((item == NULL) ||
14916
0
  (item->type == XML_SCHEMA_TYPE_BASIC) ||
14917
0
  (item->baseType == NULL))
14918
0
  return;
14919
0
    xmlSchemaCheckTypeDefCircularInternal(ctxt, item,
14920
0
  item->baseType);
14921
0
}
14922
14923
/*
14924
* Simple Type Definition Representation OK (src-simple-type) 4
14925
*
14926
* "4 Circular union type definition is disallowed. That is, if the
14927
* <union> alternative is chosen, there must not be any entries in the
14928
* memberTypes [attribute] at any depth which resolve to the component
14929
* corresponding to the <simpleType>."
14930
*
14931
* Note that this should work on the *representation* of a component,
14932
* thus assumes any union types in the member types not being yet
14933
* substituted. At this stage we need the variety of the types
14934
* to be already computed.
14935
*/
14936
static int
14937
xmlSchemaCheckUnionTypeDefCircularRecur(xmlSchemaParserCtxtPtr pctxt,
14938
          xmlSchemaTypePtr ctxType,
14939
          xmlSchemaTypeLinkPtr members)
14940
0
{
14941
0
    xmlSchemaTypeLinkPtr member;
14942
0
    xmlSchemaTypePtr memberType;
14943
14944
0
    member = members;
14945
0
    while (member != NULL) {
14946
0
  memberType = member->type;
14947
0
  while ((memberType != NULL) &&
14948
0
      (memberType->type != XML_SCHEMA_TYPE_BASIC)) {
14949
0
      if (memberType == ctxType) {
14950
0
    xmlSchemaPCustomErr(pctxt,
14951
0
        XML_SCHEMAP_SRC_SIMPLE_TYPE_4,
14952
0
        WXS_BASIC_CAST ctxType, NULL,
14953
0
        "The union type definition is circular", NULL);
14954
0
    return (XML_SCHEMAP_SRC_SIMPLE_TYPE_4);
14955
0
      }
14956
0
      if ((WXS_IS_UNION(memberType)) &&
14957
0
    ((memberType->flags & XML_SCHEMAS_TYPE_MARKED) == 0))
14958
0
      {
14959
0
    int res;
14960
0
    memberType->flags |= XML_SCHEMAS_TYPE_MARKED;
14961
0
    res = xmlSchemaCheckUnionTypeDefCircularRecur(pctxt,
14962
0
        ctxType,
14963
0
        xmlSchemaGetUnionSimpleTypeMemberTypes(memberType));
14964
0
    memberType->flags ^= XML_SCHEMAS_TYPE_MARKED;
14965
0
    if (res != 0)
14966
0
        return(res);
14967
0
      }
14968
0
      memberType = memberType->baseType;
14969
0
  }
14970
0
  member = member->next;
14971
0
    }
14972
0
    return(0);
14973
0
}
14974
14975
static int
14976
xmlSchemaCheckUnionTypeDefCircular(xmlSchemaParserCtxtPtr pctxt,
14977
           xmlSchemaTypePtr type)
14978
0
{
14979
0
    if (! WXS_IS_UNION(type))
14980
0
  return(0);
14981
0
    return(xmlSchemaCheckUnionTypeDefCircularRecur(pctxt, type,
14982
0
  type->memberTypes));
14983
0
}
14984
14985
/**
14986
 * xmlSchemaResolveTypeReferences:
14987
 * @item:  the complex/simple type definition
14988
 * @ctxt:  the parser context
14989
 * @name:  the name
14990
 *
14991
 * Resolves type definition references
14992
 */
14993
static void
14994
xmlSchemaResolveTypeReferences(xmlSchemaTypePtr typeDef,
14995
       xmlSchemaParserCtxtPtr ctxt)
14996
0
{
14997
0
    if (typeDef == NULL)
14998
0
  return;
14999
15000
    /*
15001
    * Resolve the base type.
15002
    */
15003
0
    if (typeDef->baseType == NULL) {
15004
0
  typeDef->baseType = xmlSchemaGetType(ctxt->schema,
15005
0
      typeDef->base, typeDef->baseNs);
15006
0
  if (typeDef->baseType == NULL) {
15007
0
      xmlSchemaPResCompAttrErr(ctxt,
15008
0
    XML_SCHEMAP_SRC_RESOLVE,
15009
0
    WXS_BASIC_CAST typeDef, typeDef->node,
15010
0
    "base", typeDef->base, typeDef->baseNs,
15011
0
    XML_SCHEMA_TYPE_SIMPLE, NULL);
15012
0
      return;
15013
0
  }
15014
0
    }
15015
0
    if (WXS_IS_SIMPLE(typeDef)) {
15016
0
  if (WXS_IS_UNION(typeDef)) {
15017
      /*
15018
      * Resolve the memberTypes.
15019
      */
15020
0
      xmlSchemaResolveUnionMemberTypes(ctxt, typeDef);
15021
0
      return;
15022
0
  } else if (WXS_IS_LIST(typeDef)) {
15023
      /*
15024
      * Resolve the itemType.
15025
      */
15026
0
      if ((typeDef->subtypes == NULL) && (typeDef->base != NULL)) {
15027
15028
0
    typeDef->subtypes = xmlSchemaGetType(ctxt->schema,
15029
0
        typeDef->base, typeDef->baseNs);
15030
15031
0
    if ((typeDef->subtypes == NULL) ||
15032
0
        (! WXS_IS_SIMPLE(typeDef->subtypes)))
15033
0
    {
15034
0
        typeDef->subtypes = NULL;
15035
0
        xmlSchemaPResCompAttrErr(ctxt,
15036
0
      XML_SCHEMAP_SRC_RESOLVE,
15037
0
      WXS_BASIC_CAST typeDef, typeDef->node,
15038
0
      "itemType", typeDef->base, typeDef->baseNs,
15039
0
      XML_SCHEMA_TYPE_SIMPLE, NULL);
15040
0
    }
15041
0
      }
15042
0
      return;
15043
0
  }
15044
0
    }
15045
    /*
15046
    * The ball of letters below means, that if we have a particle
15047
    * which has a QName-helper component as its {term}, we want
15048
    * to resolve it...
15049
    */
15050
0
    else if ((WXS_TYPE_CONTENTTYPE(typeDef) != NULL) &&
15051
0
  ((WXS_TYPE_CONTENTTYPE(typeDef))->type ==
15052
0
      XML_SCHEMA_TYPE_PARTICLE) &&
15053
0
  (WXS_TYPE_PARTICLE_TERM(typeDef) != NULL) &&
15054
0
  ((WXS_TYPE_PARTICLE_TERM(typeDef))->type ==
15055
0
      XML_SCHEMA_EXTRA_QNAMEREF))
15056
0
    {
15057
0
  xmlSchemaQNameRefPtr ref =
15058
0
      WXS_QNAME_CAST WXS_TYPE_PARTICLE_TERM(typeDef);
15059
0
  xmlSchemaModelGroupDefPtr groupDef;
15060
15061
  /*
15062
  * URGENT TODO: Test this.
15063
  */
15064
0
  WXS_TYPE_PARTICLE_TERM(typeDef) = NULL;
15065
  /*
15066
  * Resolve the MG definition reference.
15067
  */
15068
0
  groupDef =
15069
0
      WXS_MODEL_GROUPDEF_CAST xmlSchemaGetNamedComponent(ctxt->schema,
15070
0
    ref->itemType, ref->name, ref->targetNamespace);
15071
0
  if (groupDef == NULL) {
15072
0
      xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE,
15073
0
    NULL, WXS_ITEM_NODE(WXS_TYPE_PARTICLE(typeDef)),
15074
0
    "ref", ref->name, ref->targetNamespace, ref->itemType,
15075
0
    NULL);
15076
      /* Remove the particle. */
15077
0
      WXS_TYPE_CONTENTTYPE(typeDef) = NULL;
15078
0
  } else if (WXS_MODELGROUPDEF_MODEL(groupDef) == NULL)
15079
      /* Remove the particle. */
15080
0
      WXS_TYPE_CONTENTTYPE(typeDef) = NULL;
15081
0
  else {
15082
      /*
15083
      * Assign the MG definition's {model group} to the
15084
      * particle's {term}.
15085
      */
15086
0
      WXS_TYPE_PARTICLE_TERM(typeDef) = WXS_MODELGROUPDEF_MODEL(groupDef);
15087
15088
0
      if (WXS_MODELGROUPDEF_MODEL(groupDef)->type == XML_SCHEMA_TYPE_ALL) {
15089
    /*
15090
    * SPEC cos-all-limited (1.2)
15091
    * "1.2 the {term} property of a particle with
15092
    * {max occurs}=1 which is part of a pair which constitutes
15093
    * the {content type} of a complex type definition."
15094
    */
15095
0
    if ((WXS_TYPE_PARTICLE(typeDef))->maxOccurs != 1) {
15096
0
        xmlSchemaCustomErr(ACTXT_CAST ctxt,
15097
      /* TODO: error code */
15098
0
      XML_SCHEMAP_COS_ALL_LIMITED,
15099
0
      WXS_ITEM_NODE(WXS_TYPE_PARTICLE(typeDef)), NULL,
15100
0
      "The particle's {max occurs} must be 1, since the "
15101
0
      "reference resolves to an 'all' model group",
15102
0
      NULL, NULL);
15103
0
    }
15104
0
      }
15105
0
  }
15106
0
    }
15107
0
}
15108
15109
15110
15111
/**
15112
 * xmlSchemaCheckSTPropsCorrect:
15113
 * @ctxt:  the schema parser context
15114
 * @type:  the simple type definition
15115
 *
15116
 * Checks st-props-correct.
15117
 *
15118
 * Returns 0 if the properties are correct,
15119
 * if not, a positive error code and -1 on internal
15120
 * errors.
15121
 */
15122
static int
15123
xmlSchemaCheckSTPropsCorrect(xmlSchemaParserCtxtPtr ctxt,
15124
           xmlSchemaTypePtr type)
15125
0
{
15126
0
    xmlSchemaTypePtr baseType = type->baseType;
15127
0
    xmlChar *str = NULL;
15128
15129
    /* STATE: error funcs converted. */
15130
    /*
15131
    * Schema Component Constraint: Simple Type Definition Properties Correct
15132
    *
15133
    * NOTE: This is somehow redundant, since we actually built a simple type
15134
    * to have all the needed information; this acts as an self test.
15135
    */
15136
    /* Base type: If the datatype has been `derived` by `restriction`
15137
    * then the Simple Type Definition component from which it is `derived`,
15138
    * otherwise the Simple Type Definition for anySimpleType ($4.1.6).
15139
    */
15140
0
    if (baseType == NULL) {
15141
  /*
15142
  * TODO: Think about: "modulo the impact of Missing
15143
  * Sub-components ($5.3)."
15144
  */
15145
0
  xmlSchemaPCustomErr(ctxt,
15146
0
      XML_SCHEMAP_ST_PROPS_CORRECT_1,
15147
0
      WXS_BASIC_CAST type, NULL,
15148
0
      "No base type existent", NULL);
15149
0
  return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
15150
15151
0
    }
15152
0
    if (! WXS_IS_SIMPLE(baseType)) {
15153
0
  xmlSchemaPCustomErr(ctxt,
15154
0
      XML_SCHEMAP_ST_PROPS_CORRECT_1,
15155
0
      WXS_BASIC_CAST type, NULL,
15156
0
      "The base type '%s' is not a simple type",
15157
0
      xmlSchemaGetComponentQName(&str, baseType));
15158
0
  FREE_AND_NULL(str)
15159
0
  return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
15160
0
    }
15161
0
    if ((WXS_IS_LIST(type) || WXS_IS_UNION(type)) &&
15162
0
  (WXS_IS_RESTRICTION(type) == 0) &&
15163
0
  ((! WXS_IS_ANY_SIMPLE_TYPE(baseType)) &&
15164
0
         (baseType->type != XML_SCHEMA_TYPE_SIMPLE))) {
15165
0
  xmlSchemaPCustomErr(ctxt,
15166
0
      XML_SCHEMAP_ST_PROPS_CORRECT_1,
15167
0
      WXS_BASIC_CAST type, NULL,
15168
0
      "A type, derived by list or union, must have "
15169
0
      "the simple ur-type definition as base type, not '%s'",
15170
0
      xmlSchemaGetComponentQName(&str, baseType));
15171
0
  FREE_AND_NULL(str)
15172
0
  return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
15173
0
    }
15174
    /*
15175
    * Variety: One of {atomic, list, union}.
15176
    */
15177
0
    if ((! WXS_IS_ATOMIC(type)) && (! WXS_IS_UNION(type)) &&
15178
0
  (! WXS_IS_LIST(type))) {
15179
0
  xmlSchemaPCustomErr(ctxt,
15180
0
      XML_SCHEMAP_ST_PROPS_CORRECT_1,
15181
0
      WXS_BASIC_CAST type, NULL,
15182
0
      "The variety is absent", NULL);
15183
0
  return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
15184
0
    }
15185
    /* TODO: Finish this. Hmm, is this finished? */
15186
15187
    /*
15188
    * 3 The {final} of the {base type definition} must not contain restriction.
15189
    */
15190
0
    if (xmlSchemaTypeFinalContains(baseType,
15191
0
  XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
15192
0
  xmlSchemaPCustomErr(ctxt,
15193
0
      XML_SCHEMAP_ST_PROPS_CORRECT_3,
15194
0
      WXS_BASIC_CAST type, NULL,
15195
0
      "The 'final' of its base type '%s' must not contain "
15196
0
      "'restriction'",
15197
0
      xmlSchemaGetComponentQName(&str, baseType));
15198
0
  FREE_AND_NULL(str)
15199
0
  return (XML_SCHEMAP_ST_PROPS_CORRECT_3);
15200
0
    }
15201
15202
    /*
15203
    * 2 All simple type definitions must be derived ultimately from the `simple
15204
    * ur-type definition` (so circular definitions are disallowed). That is, it
15205
    * must be possible to reach a built-in primitive datatype or the `simple
15206
    * ur-type definition` by repeatedly following the {base type definition}.
15207
    *
15208
    * NOTE: this is done in xmlSchemaCheckTypeDefCircular().
15209
    */
15210
0
    return (0);
15211
0
}
15212
15213
/**
15214
 * xmlSchemaCheckCOSSTRestricts:
15215
 * @ctxt:  the schema parser context
15216
 * @type:  the simple type definition
15217
 *
15218
 * Schema Component Constraint:
15219
 * Derivation Valid (Restriction, Simple) (cos-st-restricts)
15220
15221
 * Checks if the given @type (simpleType) is derived validly by restriction.
15222
 * STATUS:
15223
 *
15224
 * Returns -1 on internal errors, 0 if the type is validly derived,
15225
 * a positive error code otherwise.
15226
 */
15227
static int
15228
xmlSchemaCheckCOSSTRestricts(xmlSchemaParserCtxtPtr pctxt,
15229
           xmlSchemaTypePtr type)
15230
0
{
15231
0
    xmlChar *str = NULL;
15232
15233
0
    if (type->type != XML_SCHEMA_TYPE_SIMPLE) {
15234
0
  PERROR_INT("xmlSchemaCheckCOSSTRestricts",
15235
0
      "given type is not a user-derived simpleType");
15236
0
  return (-1);
15237
0
    }
15238
15239
0
    if (WXS_IS_ATOMIC(type)) {
15240
0
  xmlSchemaTypePtr primitive;
15241
  /*
15242
  * 1.1 The {base type definition} must be an atomic simple
15243
  * type definition or a built-in primitive datatype.
15244
  */
15245
0
  if (! WXS_IS_ATOMIC(type->baseType)) {
15246
0
      xmlSchemaPCustomErr(pctxt,
15247
0
    XML_SCHEMAP_COS_ST_RESTRICTS_1_1,
15248
0
    WXS_BASIC_CAST type, NULL,
15249
0
    "The base type '%s' is not an atomic simple type",
15250
0
    xmlSchemaGetComponentQName(&str, type->baseType));
15251
0
      FREE_AND_NULL(str)
15252
0
      return (XML_SCHEMAP_COS_ST_RESTRICTS_1_1);
15253
0
  }
15254
  /* 1.2 The {final} of the {base type definition} must not contain
15255
  * restriction.
15256
  */
15257
  /* OPTIMIZE TODO : This is already done in xmlSchemaCheckStPropsCorrect */
15258
0
  if (xmlSchemaTypeFinalContains(type->baseType,
15259
0
      XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
15260
0
      xmlSchemaPCustomErr(pctxt,
15261
0
    XML_SCHEMAP_COS_ST_RESTRICTS_1_2,
15262
0
    WXS_BASIC_CAST type, NULL,
15263
0
    "The final of its base type '%s' must not contain 'restriction'",
15264
0
    xmlSchemaGetComponentQName(&str, type->baseType));
15265
0
      FREE_AND_NULL(str)
15266
0
      return (XML_SCHEMAP_COS_ST_RESTRICTS_1_2);
15267
0
  }
15268
15269
  /*
15270
  * 1.3.1 DF must be an allowed constraining facet for the {primitive
15271
  * type definition}, as specified in the appropriate subsection of 3.2
15272
  * Primitive datatypes.
15273
  */
15274
0
  if (type->facets != NULL) {
15275
0
      xmlSchemaFacetPtr facet;
15276
0
      int ok = 1;
15277
15278
0
      primitive = xmlSchemaGetPrimitiveType(type);
15279
0
      if (primitive == NULL) {
15280
0
    PERROR_INT("xmlSchemaCheckCOSSTRestricts",
15281
0
        "failed to get primitive type");
15282
0
    return (-1);
15283
0
      }
15284
0
      facet = type->facets;
15285
0
      do {
15286
0
    if (xmlSchemaIsBuiltInTypeFacet(primitive, facet->type) == 0) {
15287
0
        ok = 0;
15288
0
        xmlSchemaPIllegalFacetAtomicErr(pctxt,
15289
0
      XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1,
15290
0
      type, primitive, facet);
15291
0
    }
15292
0
    facet = facet->next;
15293
0
      } while (facet != NULL);
15294
0
      if (ok == 0)
15295
0
    return (XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1);
15296
0
  }
15297
  /*
15298
  * SPEC (1.3.2) "If there is a facet of the same kind in the {facets}
15299
  * of the {base type definition} (call this BF),then the DF's {value}
15300
  * must be a valid restriction of BF's {value} as defined in
15301
  * [XML Schemas: Datatypes]."
15302
  *
15303
  * NOTE (1.3.2) Facet derivation constraints are currently handled in
15304
  * xmlSchemaDeriveAndValidateFacets()
15305
  */
15306
0
    } else if (WXS_IS_LIST(type)) {
15307
0
  xmlSchemaTypePtr itemType = NULL;
15308
15309
0
  itemType = type->subtypes;
15310
0
  if ((itemType == NULL) || (! WXS_IS_SIMPLE(itemType))) {
15311
0
      PERROR_INT("xmlSchemaCheckCOSSTRestricts",
15312
0
    "failed to evaluate the item type");
15313
0
      return (-1);
15314
0
  }
15315
0
  if (WXS_IS_TYPE_NOT_FIXED(itemType))
15316
0
      xmlSchemaTypeFixup(itemType, ACTXT_CAST pctxt);
15317
  /*
15318
  * 2.1 The {item type definition} must have a {variety} of atomic or
15319
  * union (in which case all the {member type definitions}
15320
  * must be atomic).
15321
  */
15322
0
  if ((! WXS_IS_ATOMIC(itemType)) &&
15323
0
      (! WXS_IS_UNION(itemType))) {
15324
0
      xmlSchemaPCustomErr(pctxt,
15325
0
    XML_SCHEMAP_COS_ST_RESTRICTS_2_1,
15326
0
    WXS_BASIC_CAST type, NULL,
15327
0
    "The item type '%s' does not have a variety of atomic or union",
15328
0
    xmlSchemaGetComponentQName(&str, itemType));
15329
0
      FREE_AND_NULL(str)
15330
0
      return (XML_SCHEMAP_COS_ST_RESTRICTS_2_1);
15331
0
  } else if (WXS_IS_UNION(itemType)) {
15332
0
      xmlSchemaTypeLinkPtr member;
15333
15334
0
      member = itemType->memberTypes;
15335
0
      while (member != NULL) {
15336
0
    if (! WXS_IS_ATOMIC(member->type)) {
15337
0
        xmlSchemaPCustomErr(pctxt,
15338
0
      XML_SCHEMAP_COS_ST_RESTRICTS_2_1,
15339
0
      WXS_BASIC_CAST type, NULL,
15340
0
      "The item type is a union type, but the "
15341
0
      "member type '%s' of this item type is not atomic",
15342
0
      xmlSchemaGetComponentQName(&str, member->type));
15343
0
        FREE_AND_NULL(str)
15344
0
        return (XML_SCHEMAP_COS_ST_RESTRICTS_2_1);
15345
0
    }
15346
0
    member = member->next;
15347
0
      }
15348
0
  }
15349
15350
0
  if (WXS_IS_ANY_SIMPLE_TYPE(type->baseType)) {
15351
0
      xmlSchemaFacetPtr facet;
15352
      /*
15353
      * This is the case if we have: <simpleType><list ..
15354
      */
15355
      /*
15356
      * 2.3.1
15357
      * 2.3.1.1 The {final} of the {item type definition} must not
15358
      * contain list.
15359
      */
15360
0
      if (xmlSchemaTypeFinalContains(itemType,
15361
0
    XML_SCHEMAS_TYPE_FINAL_LIST)) {
15362
0
    xmlSchemaPCustomErr(pctxt,
15363
0
        XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1,
15364
0
        WXS_BASIC_CAST type, NULL,
15365
0
        "The final of its item type '%s' must not contain 'list'",
15366
0
        xmlSchemaGetComponentQName(&str, itemType));
15367
0
    FREE_AND_NULL(str)
15368
0
    return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1);
15369
0
      }
15370
      /*
15371
      * 2.3.1.2 The {facets} must only contain the whiteSpace
15372
      * facet component.
15373
      * OPTIMIZE TODO: the S4S already disallows any facet
15374
      * to be specified.
15375
      */
15376
0
      if (type->facets != NULL) {
15377
0
    facet = type->facets;
15378
0
    do {
15379
0
        if (facet->type != XML_SCHEMA_FACET_WHITESPACE) {
15380
0
      xmlSchemaPIllegalFacetListUnionErr(pctxt,
15381
0
          XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2,
15382
0
          type, facet);
15383
0
      return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2);
15384
0
        }
15385
0
        facet = facet->next;
15386
0
    } while (facet != NULL);
15387
0
      }
15388
      /*
15389
      * MAYBE TODO: (Hmm, not really) Datatypes states:
15390
      * A `list` datatype can be `derived` from an `atomic` datatype
15391
      * whose `lexical space` allows space (such as string or anyURI)or
15392
      * a `union` datatype any of whose {member type definitions}'s
15393
      * `lexical space` allows space.
15394
      */
15395
0
  } else {
15396
      /*
15397
      * This is the case if we have: <simpleType><restriction ...
15398
      * I.e. the variety of "list" is inherited.
15399
      */
15400
      /*
15401
      * 2.3.2
15402
      * 2.3.2.1 The {base type definition} must have a {variety} of list.
15403
      */
15404
0
      if (! WXS_IS_LIST(type->baseType)) {
15405
0
    xmlSchemaPCustomErr(pctxt,
15406
0
        XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1,
15407
0
        WXS_BASIC_CAST type, NULL,
15408
0
        "The base type '%s' must be a list type",
15409
0
        xmlSchemaGetComponentQName(&str, type->baseType));
15410
0
    FREE_AND_NULL(str)
15411
0
    return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1);
15412
0
      }
15413
      /*
15414
      * 2.3.2.2 The {final} of the {base type definition} must not
15415
      * contain restriction.
15416
      */
15417
0
      if (xmlSchemaTypeFinalContains(type->baseType,
15418
0
    XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
15419
0
    xmlSchemaPCustomErr(pctxt,
15420
0
        XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2,
15421
0
        WXS_BASIC_CAST type, NULL,
15422
0
        "The 'final' of the base type '%s' must not contain 'restriction'",
15423
0
        xmlSchemaGetComponentQName(&str, type->baseType));
15424
0
    FREE_AND_NULL(str)
15425
0
    return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2);
15426
0
      }
15427
      /*
15428
      * 2.3.2.3 The {item type definition} must be validly derived
15429
      * from the {base type definition}'s {item type definition} given
15430
      * the empty set, as defined in Type Derivation OK (Simple) ($3.14.6).
15431
      */
15432
0
      {
15433
0
    xmlSchemaTypePtr baseItemType;
15434
15435
0
    baseItemType = type->baseType->subtypes;
15436
0
    if ((baseItemType == NULL) || (! WXS_IS_SIMPLE(baseItemType))) {
15437
0
        PERROR_INT("xmlSchemaCheckCOSSTRestricts",
15438
0
      "failed to eval the item type of a base type");
15439
0
        return (-1);
15440
0
    }
15441
0
    if ((itemType != baseItemType) &&
15442
0
        (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt, itemType,
15443
0
      baseItemType, 0) != 0)) {
15444
0
        xmlChar *strBIT = NULL, *strBT = NULL;
15445
0
        xmlSchemaPCustomErrExt(pctxt,
15446
0
      XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3,
15447
0
      WXS_BASIC_CAST type, NULL,
15448
0
      "The item type '%s' is not validly derived from "
15449
0
      "the item type '%s' of the base type '%s'",
15450
0
      xmlSchemaGetComponentQName(&str, itemType),
15451
0
      xmlSchemaGetComponentQName(&strBIT, baseItemType),
15452
0
      xmlSchemaGetComponentQName(&strBT, type->baseType));
15453
15454
0
        FREE_AND_NULL(str)
15455
0
        FREE_AND_NULL(strBIT)
15456
0
        FREE_AND_NULL(strBT)
15457
0
        return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3);
15458
0
    }
15459
0
      }
15460
15461
0
      if (type->facets != NULL) {
15462
0
    xmlSchemaFacetPtr facet;
15463
0
    int ok = 1;
15464
    /*
15465
    * 2.3.2.4 Only length, minLength, maxLength, whiteSpace, pattern
15466
    * and enumeration facet components are allowed among the {facets}.
15467
    */
15468
0
    facet = type->facets;
15469
0
    do {
15470
0
        switch (facet->type) {
15471
0
      case XML_SCHEMA_FACET_LENGTH:
15472
0
      case XML_SCHEMA_FACET_MINLENGTH:
15473
0
      case XML_SCHEMA_FACET_MAXLENGTH:
15474
0
      case XML_SCHEMA_FACET_WHITESPACE:
15475
          /*
15476
          * TODO: 2.5.1.2 List datatypes
15477
          * The value of `whiteSpace` is fixed to the value collapse.
15478
          */
15479
0
      case XML_SCHEMA_FACET_PATTERN:
15480
0
      case XML_SCHEMA_FACET_ENUMERATION:
15481
0
          break;
15482
0
      default: {
15483
0
          xmlSchemaPIllegalFacetListUnionErr(pctxt,
15484
0
        XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4,
15485
0
        type, facet);
15486
          /*
15487
          * We could return, but it's nicer to report all
15488
          * invalid facets.
15489
          */
15490
0
          ok = 0;
15491
0
      }
15492
0
        }
15493
0
        facet = facet->next;
15494
0
    } while (facet != NULL);
15495
0
    if (ok == 0)
15496
0
        return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4);
15497
    /*
15498
    * SPEC (2.3.2.5) (same as 1.3.2)
15499
    *
15500
    * NOTE (2.3.2.5) This is currently done in
15501
    * xmlSchemaDeriveAndValidateFacets()
15502
    */
15503
0
      }
15504
0
  }
15505
0
    } else if (WXS_IS_UNION(type)) {
15506
  /*
15507
  * 3.1 The {member type definitions} must all have {variety} of
15508
  * atomic or list.
15509
  */
15510
0
  xmlSchemaTypeLinkPtr member;
15511
15512
0
  member = type->memberTypes;
15513
0
  while (member != NULL) {
15514
0
      if (WXS_IS_TYPE_NOT_FIXED(member->type))
15515
0
    xmlSchemaTypeFixup(member->type, ACTXT_CAST pctxt);
15516
15517
0
      if ((! WXS_IS_ATOMIC(member->type)) &&
15518
0
    (! WXS_IS_LIST(member->type))) {
15519
0
    xmlSchemaPCustomErr(pctxt,
15520
0
        XML_SCHEMAP_COS_ST_RESTRICTS_3_1,
15521
0
        WXS_BASIC_CAST type, NULL,
15522
0
        "The member type '%s' is neither an atomic, nor a list type",
15523
0
        xmlSchemaGetComponentQName(&str, member->type));
15524
0
    FREE_AND_NULL(str)
15525
0
    return (XML_SCHEMAP_COS_ST_RESTRICTS_3_1);
15526
0
      }
15527
0
      member = member->next;
15528
0
  }
15529
  /*
15530
  * 3.3.1 If the {base type definition} is the `simple ur-type
15531
  * definition`
15532
  */
15533
0
  if (type->baseType->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) {
15534
      /*
15535
      * 3.3.1.1 All of the {member type definitions} must have a
15536
      * {final} which does not contain union.
15537
      */
15538
0
      member = type->memberTypes;
15539
0
      while (member != NULL) {
15540
0
    if (xmlSchemaTypeFinalContains(member->type,
15541
0
        XML_SCHEMAS_TYPE_FINAL_UNION)) {
15542
0
        xmlSchemaPCustomErr(pctxt,
15543
0
      XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1,
15544
0
      WXS_BASIC_CAST type, NULL,
15545
0
      "The 'final' of member type '%s' contains 'union'",
15546
0
      xmlSchemaGetComponentQName(&str, member->type));
15547
0
        FREE_AND_NULL(str)
15548
0
        return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1);
15549
0
    }
15550
0
    member = member->next;
15551
0
      }
15552
      /*
15553
      * 3.3.1.2 The {facets} must be empty.
15554
      */
15555
0
      if (type->facetSet != NULL) {
15556
0
    xmlSchemaPCustomErr(pctxt,
15557
0
        XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2,
15558
0
        WXS_BASIC_CAST type, NULL,
15559
0
        "No facets allowed", NULL);
15560
0
    return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2);
15561
0
      }
15562
0
  } else {
15563
      /*
15564
      * 3.3.2.1 The {base type definition} must have a {variety} of union.
15565
      * I.e. the variety of "list" is inherited.
15566
      */
15567
0
      if (! WXS_IS_UNION(type->baseType)) {
15568
0
    xmlSchemaPCustomErr(pctxt,
15569
0
        XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1,
15570
0
        WXS_BASIC_CAST type, NULL,
15571
0
        "The base type '%s' is not a union type",
15572
0
        xmlSchemaGetComponentQName(&str, type->baseType));
15573
0
    FREE_AND_NULL(str)
15574
0
    return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1);
15575
0
      }
15576
      /*
15577
      * 3.3.2.2 The {final} of the {base type definition} must not contain restriction.
15578
      */
15579
0
      if (xmlSchemaTypeFinalContains(type->baseType,
15580
0
    XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
15581
0
    xmlSchemaPCustomErr(pctxt,
15582
0
        XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2,
15583
0
        WXS_BASIC_CAST type, NULL,
15584
0
        "The 'final' of its base type '%s' must not contain 'restriction'",
15585
0
        xmlSchemaGetComponentQName(&str, type->baseType));
15586
0
    FREE_AND_NULL(str)
15587
0
    return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2);
15588
0
      }
15589
      /*
15590
      * 3.3.2.3 The {member type definitions}, in order, must be validly
15591
      * derived from the corresponding type definitions in the {base
15592
      * type definition}'s {member type definitions} given the empty set,
15593
      * as defined in Type Derivation OK (Simple) ($3.14.6).
15594
      */
15595
0
      {
15596
0
    xmlSchemaTypeLinkPtr baseMember;
15597
15598
    /*
15599
    * OPTIMIZE: if the type is restricting, it has no local defined
15600
    * member types and inherits the member types of the base type;
15601
    * thus a check for equality can be skipped.
15602
    */
15603
    /*
15604
    * Even worse: I cannot see a scenario where a restricting
15605
    * union simple type can have other member types as the member
15606
    * types of it's base type. This check seems not necessary with
15607
    * respect to the derivation process in libxml2.
15608
    * But necessary if constructing types with an API.
15609
    */
15610
0
    if (type->memberTypes != NULL) {
15611
0
        member = type->memberTypes;
15612
0
        baseMember = xmlSchemaGetUnionSimpleTypeMemberTypes(type->baseType);
15613
0
        if ((member == NULL) && (baseMember != NULL)) {
15614
0
      PERROR_INT("xmlSchemaCheckCOSSTRestricts",
15615
0
          "different number of member types in base");
15616
0
        }
15617
0
        while (member != NULL) {
15618
0
      if (baseMember == NULL) {
15619
0
          PERROR_INT("xmlSchemaCheckCOSSTRestricts",
15620
0
          "different number of member types in base");
15621
0
      } else if ((member->type != baseMember->type) &&
15622
0
          (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt,
15623
0
        member->type, baseMember->type, 0) != 0)) {
15624
0
          xmlChar *strBMT = NULL, *strBT = NULL;
15625
15626
0
          xmlSchemaPCustomErrExt(pctxt,
15627
0
        XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3,
15628
0
        WXS_BASIC_CAST type, NULL,
15629
0
        "The member type %s is not validly "
15630
0
        "derived from its corresponding member "
15631
0
        "type %s of the base type %s",
15632
0
        xmlSchemaGetComponentQName(&str, member->type),
15633
0
        xmlSchemaGetComponentQName(&strBMT, baseMember->type),
15634
0
        xmlSchemaGetComponentQName(&strBT, type->baseType));
15635
0
          FREE_AND_NULL(str)
15636
0
          FREE_AND_NULL(strBMT)
15637
0
          FREE_AND_NULL(strBT)
15638
0
          return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3);
15639
0
      }
15640
0
      member = member->next;
15641
0
                        if (baseMember != NULL)
15642
0
                            baseMember = baseMember->next;
15643
0
        }
15644
0
    }
15645
0
      }
15646
      /*
15647
      * 3.3.2.4 Only pattern and enumeration facet components are
15648
      * allowed among the {facets}.
15649
      */
15650
0
      if (type->facets != NULL) {
15651
0
    xmlSchemaFacetPtr facet;
15652
0
    int ok = 1;
15653
15654
0
    facet = type->facets;
15655
0
    do {
15656
0
        if ((facet->type != XML_SCHEMA_FACET_PATTERN) &&
15657
0
      (facet->type != XML_SCHEMA_FACET_ENUMERATION)) {
15658
0
      xmlSchemaPIllegalFacetListUnionErr(pctxt,
15659
0
        XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4,
15660
0
        type, facet);
15661
0
      ok = 0;
15662
0
        }
15663
0
        facet = facet->next;
15664
0
    } while (facet != NULL);
15665
0
    if (ok == 0)
15666
0
        return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4);
15667
15668
0
      }
15669
      /*
15670
      * SPEC (3.3.2.5) (same as 1.3.2)
15671
      *
15672
      * NOTE (3.3.2.5) This is currently done in
15673
      * xmlSchemaDeriveAndValidateFacets()
15674
      */
15675
0
  }
15676
0
    }
15677
15678
0
    return (0);
15679
0
}
15680
15681
/**
15682
 * xmlSchemaCheckSRCSimpleType:
15683
 * @ctxt:  the schema parser context
15684
 * @type:  the simple type definition
15685
 *
15686
 * Checks crc-simple-type constraints.
15687
 *
15688
 * Returns 0 if the constraints are satisfied,
15689
 * if not a positive error code and -1 on internal
15690
 * errors.
15691
 */
15692
#if 0
15693
static int
15694
xmlSchemaCheckSRCSimpleType(xmlSchemaParserCtxtPtr ctxt,
15695
          xmlSchemaTypePtr type)
15696
{
15697
    /*
15698
    * src-simple-type.1 The corresponding simple type definition, if any,
15699
    * must satisfy the conditions set out in Constraints on Simple Type
15700
    * Definition Schema Components ($3.14.6).
15701
    */
15702
    if (WXS_IS_RESTRICTION(type)) {
15703
  /*
15704
  * src-simple-type.2 "If the <restriction> alternative is chosen,
15705
  * either it must have a base [attribute] or a <simpleType> among its
15706
  * [children], but not both."
15707
  * NOTE: This is checked in the parse function of <restriction>.
15708
  */
15709
  /*
15710
  *
15711
  */
15712
    } else if (WXS_IS_LIST(type)) {
15713
  /* src-simple-type.3 "If the <list> alternative is chosen, either it must have
15714
  * an itemType [attribute] or a <simpleType> among its [children],
15715
  * but not both."
15716
  *
15717
  * NOTE: This is checked in the parse function of <list>.
15718
  */
15719
    } else if (WXS_IS_UNION(type)) {
15720
  /*
15721
  * src-simple-type.4 is checked in xmlSchemaCheckUnionTypeDefCircular().
15722
  */
15723
    }
15724
    return (0);
15725
}
15726
#endif
15727
15728
static int
15729
xmlSchemaCreateVCtxtOnPCtxt(xmlSchemaParserCtxtPtr ctxt)
15730
0
{
15731
0
   if (ctxt->vctxt == NULL) {
15732
0
  ctxt->vctxt = xmlSchemaNewValidCtxt(NULL);
15733
0
  if (ctxt->vctxt == NULL) {
15734
0
      xmlSchemaPErr(ctxt, NULL,
15735
0
    XML_SCHEMAP_INTERNAL,
15736
0
    "Internal error: xmlSchemaCreateVCtxtOnPCtxt, "
15737
0
    "failed to create a temp. validation context.\n",
15738
0
    NULL, NULL);
15739
0
      return (-1);
15740
0
  }
15741
  /* TODO: Pass user data. */
15742
0
  xmlSchemaSetValidErrors(ctxt->vctxt,
15743
0
      ctxt->error, ctxt->warning, ctxt->errCtxt);
15744
0
  xmlSchemaSetValidStructuredErrors(ctxt->vctxt,
15745
0
      ctxt->serror, ctxt->errCtxt);
15746
0
    }
15747
0
    return (0);
15748
0
}
15749
15750
static int
15751
xmlSchemaVCheckCVCSimpleType(xmlSchemaAbstractCtxtPtr actxt,
15752
           xmlNodePtr node,
15753
           xmlSchemaTypePtr type,
15754
           const xmlChar *value,
15755
           xmlSchemaValPtr *retVal,
15756
           int fireErrors,
15757
           int normalize,
15758
           int isNormalized);
15759
15760
/**
15761
 * xmlSchemaParseCheckCOSValidDefault:
15762
 * @pctxt:  the schema parser context
15763
 * @type:  the simple type definition
15764
 * @value: the default value
15765
 * @node: an optional node (the holder of the value)
15766
 *
15767
 * Schema Component Constraint: Element Default Valid (Immediate)
15768
 * (cos-valid-default)
15769
 * This will be used by the parser only. For the validator there's
15770
 * an other version.
15771
 *
15772
 * Returns 0 if the constraints are satisfied,
15773
 * if not, a positive error code and -1 on internal
15774
 * errors.
15775
 */
15776
static int
15777
xmlSchemaParseCheckCOSValidDefault(xmlSchemaParserCtxtPtr pctxt,
15778
           xmlNodePtr node,
15779
           xmlSchemaTypePtr type,
15780
           const xmlChar *value,
15781
           xmlSchemaValPtr *val)
15782
0
{
15783
0
    int ret = 0;
15784
15785
    /*
15786
    * cos-valid-default:
15787
    * Schema Component Constraint: Element Default Valid (Immediate)
15788
    * For a string to be a valid default with respect to a type
15789
    * definition the appropriate case among the following must be true:
15790
    */
15791
0
    if WXS_IS_COMPLEX(type) {
15792
  /*
15793
  * Complex type.
15794
  *
15795
  * SPEC (2.1) "its {content type} must be a simple type definition
15796
  * or mixed."
15797
  * SPEC (2.2.2) "If the {content type} is mixed, then the {content
15798
  * type}'s particle must be `emptiable` as defined by
15799
  * Particle Emptiable ($3.9.6)."
15800
  */
15801
0
  if ((! WXS_HAS_SIMPLE_CONTENT(type)) &&
15802
0
      ((! WXS_HAS_MIXED_CONTENT(type)) || (! WXS_EMPTIABLE(type)))) {
15803
      /* NOTE that this covers (2.2.2) as well. */
15804
0
      xmlSchemaPCustomErr(pctxt,
15805
0
    XML_SCHEMAP_COS_VALID_DEFAULT_2_1,
15806
0
    WXS_BASIC_CAST type, type->node,
15807
0
    "For a string to be a valid default, the type definition "
15808
0
    "must be a simple type or a complex type with mixed content "
15809
0
    "and a particle emptiable", NULL);
15810
0
      return(XML_SCHEMAP_COS_VALID_DEFAULT_2_1);
15811
0
  }
15812
0
    }
15813
    /*
15814
    * 1 If the type definition is a simple type definition, then the string
15815
    * must be `valid` with respect to that definition as defined by String
15816
    * Valid ($3.14.4).
15817
    *
15818
    * AND
15819
    *
15820
    * 2.2.1 If the {content type} is a simple type definition, then the
15821
    * string must be `valid` with respect to that simple type definition
15822
    * as defined by String Valid ($3.14.4).
15823
    */
15824
0
    if (WXS_IS_SIMPLE(type))
15825
0
  ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt, node,
15826
0
      type, value, val, 1, 1, 0);
15827
0
    else if (WXS_HAS_SIMPLE_CONTENT(type))
15828
0
  ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt, node,
15829
0
      type->contentTypeDef, value, val, 1, 1, 0);
15830
0
    else
15831
0
  return (ret);
15832
15833
0
    if (ret < 0) {
15834
0
  PERROR_INT("xmlSchemaParseCheckCOSValidDefault",
15835
0
      "calling xmlSchemaVCheckCVCSimpleType()");
15836
0
    }
15837
15838
0
    return (ret);
15839
0
}
15840
15841
/**
15842
 * xmlSchemaCheckCTPropsCorrect:
15843
 * @ctxt:  the schema parser context
15844
 * @type:  the complex type definition
15845
 *
15846
 *.(4.6) Constraints on Complex Type Definition Schema Components
15847
 * Schema Component Constraint:
15848
 * Complex Type Definition Properties Correct (ct-props-correct)
15849
 * STATUS: (seems) complete
15850
 *
15851
 * Returns 0 if the constraints are satisfied, a positive
15852
 * error code if not and -1 if an internal error occurred.
15853
 */
15854
static int
15855
xmlSchemaCheckCTPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
15856
           xmlSchemaTypePtr type)
15857
0
{
15858
    /*
15859
    * TODO: Correct the error code; XML_SCHEMAP_SRC_CT_1 is used temporarily.
15860
    *
15861
    * SPEC (1) "The values of the properties of a complex type definition must
15862
    * be as described in the property tableau in The Complex Type Definition
15863
    * Schema Component ($3.4.1), modulo the impact of Missing
15864
    * Sub-components ($5.3)."
15865
    */
15866
0
    if ((type->baseType != NULL) &&
15867
0
  (WXS_IS_SIMPLE(type->baseType)) &&
15868
0
  (WXS_IS_EXTENSION(type) == 0)) {
15869
  /*
15870
  * SPEC (2) "If the {base type definition} is a simple type definition,
15871
  * the {derivation method} must be extension."
15872
  */
15873
0
  xmlSchemaCustomErr(ACTXT_CAST pctxt,
15874
0
      XML_SCHEMAP_SRC_CT_1,
15875
0
      NULL, WXS_BASIC_CAST type,
15876
0
      "If the base type is a simple type, the derivation method must be "
15877
0
      "'extension'", NULL, NULL);
15878
0
  return (XML_SCHEMAP_SRC_CT_1);
15879
0
    }
15880
    /*
15881
    * SPEC (3) "Circular definitions are disallowed, except for the `ur-type
15882
    * definition`. That is, it must be possible to reach the `ur-type
15883
    * definition` by repeatedly following the {base type definition}."
15884
    *
15885
    * NOTE (3) is done in xmlSchemaCheckTypeDefCircular().
15886
    */
15887
    /*
15888
    * NOTE that (4) and (5) need the following:
15889
    *   - attribute uses need to be already inherited (apply attr. prohibitions)
15890
    *   - attribute group references need to be expanded already
15891
    *   - simple types need to be typefixed already
15892
    */
15893
0
    if (type->attrUses &&
15894
0
  (((xmlSchemaItemListPtr) type->attrUses)->nbItems > 1))
15895
0
    {
15896
0
  xmlSchemaItemListPtr uses = (xmlSchemaItemListPtr) type->attrUses;
15897
0
  xmlSchemaAttributeUsePtr use, tmp;
15898
0
  int i, j, hasId = 0;
15899
15900
0
  for (i = uses->nbItems -1; i >= 0; i--) {
15901
0
      use = uses->items[i];
15902
15903
      /*
15904
      * SPEC ct-props-correct
15905
      * (4) "Two distinct attribute declarations in the
15906
      * {attribute uses} must not have identical {name}s and
15907
      * {target namespace}s."
15908
      */
15909
0
      if (i > 0) {
15910
0
    for (j = i -1; j >= 0; j--) {
15911
0
        tmp = uses->items[j];
15912
0
        if ((WXS_ATTRUSE_DECL_NAME(use) ==
15913
0
      WXS_ATTRUSE_DECL_NAME(tmp)) &&
15914
0
      (WXS_ATTRUSE_DECL_TNS(use) ==
15915
0
      WXS_ATTRUSE_DECL_TNS(tmp)))
15916
0
        {
15917
0
      xmlChar *str = NULL;
15918
15919
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
15920
0
          XML_SCHEMAP_AG_PROPS_CORRECT,
15921
0
          NULL, WXS_BASIC_CAST type,
15922
0
          "Duplicate %s",
15923
0
          xmlSchemaGetComponentDesignation(&str, use),
15924
0
          NULL);
15925
0
      FREE_AND_NULL(str);
15926
      /*
15927
      * Remove the duplicate.
15928
      */
15929
0
      if (xmlSchemaItemListRemove(uses, i) == -1)
15930
0
          goto exit_failure;
15931
0
      goto next_use;
15932
0
        }
15933
0
    }
15934
0
      }
15935
      /*
15936
      * SPEC ct-props-correct
15937
      * (5) "Two distinct attribute declarations in the
15938
      * {attribute uses} must not have {type definition}s which
15939
      * are or are derived from ID."
15940
      */
15941
0
      if (WXS_ATTRUSE_TYPEDEF(use) != NULL) {
15942
0
    if (xmlSchemaIsDerivedFromBuiltInType(
15943
0
        WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID))
15944
0
    {
15945
0
        if (hasId) {
15946
0
      xmlChar *str = NULL;
15947
15948
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
15949
0
          XML_SCHEMAP_AG_PROPS_CORRECT,
15950
0
          NULL, WXS_BASIC_CAST type,
15951
0
          "There must not exist more than one attribute "
15952
0
          "declaration of type 'xs:ID' "
15953
0
          "(or derived from 'xs:ID'). The %s violates this "
15954
0
          "constraint",
15955
0
          xmlSchemaGetComponentDesignation(&str, use),
15956
0
          NULL);
15957
0
      FREE_AND_NULL(str);
15958
0
      if (xmlSchemaItemListRemove(uses, i) == -1)
15959
0
          goto exit_failure;
15960
0
        }
15961
15962
0
        hasId = 1;
15963
0
    }
15964
0
      }
15965
0
next_use: {}
15966
0
  }
15967
0
    }
15968
0
    return (0);
15969
0
exit_failure:
15970
0
    return(-1);
15971
0
}
15972
15973
static int
15974
xmlSchemaAreEqualTypes(xmlSchemaTypePtr typeA,
15975
           xmlSchemaTypePtr typeB)
15976
0
{
15977
    /*
15978
    * TODO: This should implement component-identity
15979
    * in the future.
15980
    */
15981
0
    if ((typeA == NULL) || (typeB == NULL))
15982
0
  return (0);
15983
0
    return (typeA == typeB);
15984
0
}
15985
15986
/**
15987
 * xmlSchemaCheckCOSCTDerivedOK:
15988
 * @ctxt:  the schema parser context
15989
 * @type:  the to-be derived complex type definition
15990
 * @baseType:  the base complex type definition
15991
 * @set: the given set
15992
 *
15993
 * Schema Component Constraint:
15994
 * Type Derivation OK (Complex) (cos-ct-derived-ok)
15995
 *
15996
 * STATUS: completed
15997
 *
15998
 * Returns 0 if the constraints are satisfied, or 1
15999
 * if not.
16000
 */
16001
static int
16002
xmlSchemaCheckCOSCTDerivedOK(xmlSchemaAbstractCtxtPtr actxt,
16003
           xmlSchemaTypePtr type,
16004
           xmlSchemaTypePtr baseType,
16005
           int set)
16006
0
{
16007
0
    int equal = xmlSchemaAreEqualTypes(type, baseType);
16008
    /* TODO: Error codes. */
16009
    /*
16010
    * SPEC "For a complex type definition (call it D, for derived)
16011
    * to be validly derived from a type definition (call this
16012
    * B, for base) given a subset of {extension, restriction}
16013
    * all of the following must be true:"
16014
    */
16015
0
    if (! equal) {
16016
  /*
16017
  * SPEC (1) "If B and D are not the same type definition, then the
16018
  * {derivation method} of D must not be in the subset."
16019
  */
16020
0
  if (((set & SUBSET_EXTENSION) && (WXS_IS_EXTENSION(type))) ||
16021
0
      ((set & SUBSET_RESTRICTION) && (WXS_IS_RESTRICTION(type))))
16022
0
      return (1);
16023
0
    } else {
16024
  /*
16025
  * SPEC (2.1) "B and D must be the same type definition."
16026
  */
16027
0
  return (0);
16028
0
    }
16029
    /*
16030
    * SPEC (2.2) "B must be D's {base type definition}."
16031
    */
16032
0
    if (type->baseType == baseType)
16033
0
  return (0);
16034
    /*
16035
    * SPEC (2.3.1) "D's {base type definition} must not be the `ur-type
16036
    * definition`."
16037
    */
16038
0
    if (WXS_IS_ANYTYPE(type->baseType))
16039
0
  return (1);
16040
16041
0
    if (WXS_IS_COMPLEX(type->baseType)) {
16042
  /*
16043
  * SPEC (2.3.2.1) "If D's {base type definition} is complex, then it
16044
  * must be validly derived from B given the subset as defined by this
16045
  * constraint."
16046
  */
16047
0
  return (xmlSchemaCheckCOSCTDerivedOK(actxt, type->baseType,
16048
0
      baseType, set));
16049
0
    } else {
16050
  /*
16051
  * SPEC (2.3.2.2) "If D's {base type definition} is simple, then it
16052
  * must be validly derived from B given the subset as defined in Type
16053
  * Derivation OK (Simple) ($3.14.6).
16054
  */
16055
0
  return (xmlSchemaCheckCOSSTDerivedOK(actxt, type->baseType,
16056
0
      baseType, set));
16057
0
    }
16058
0
}
16059
16060
/**
16061
 * xmlSchemaCheckCOSDerivedOK:
16062
 * @type:  the derived simple type definition
16063
 * @baseType:  the base type definition
16064
 *
16065
 * Calls:
16066
 * Type Derivation OK (Simple) AND Type Derivation OK (Complex)
16067
 *
16068
 * Checks whether @type can be validly derived from @baseType.
16069
 *
16070
 * Returns 0 on success, an positive error code otherwise.
16071
 */
16072
static int
16073
xmlSchemaCheckCOSDerivedOK(xmlSchemaAbstractCtxtPtr actxt,
16074
         xmlSchemaTypePtr type,
16075
         xmlSchemaTypePtr baseType,
16076
         int set)
16077
0
{
16078
0
    if (WXS_IS_SIMPLE(type))
16079
0
  return (xmlSchemaCheckCOSSTDerivedOK(actxt, type, baseType, set));
16080
0
    else
16081
0
  return (xmlSchemaCheckCOSCTDerivedOK(actxt, type, baseType, set));
16082
0
}
16083
16084
/**
16085
 * xmlSchemaCheckCOSCTExtends:
16086
 * @ctxt:  the schema parser context
16087
 * @type:  the complex type definition
16088
 *
16089
 * (3.4.6) Constraints on Complex Type Definition Schema Components
16090
 * Schema Component Constraint:
16091
 * Derivation Valid (Extension) (cos-ct-extends)
16092
 *
16093
 * STATUS:
16094
 *   missing:
16095
 *     (1.5)
16096
 *     (1.4.3.2.2.2) "Particle Valid (Extension)"
16097
 *
16098
 * Returns 0 if the constraints are satisfied, a positive
16099
 * error code if not and -1 if an internal error occurred.
16100
 */
16101
static int
16102
xmlSchemaCheckCOSCTExtends(xmlSchemaParserCtxtPtr ctxt,
16103
         xmlSchemaTypePtr type)
16104
0
{
16105
0
    xmlSchemaTypePtr base = type->baseType;
16106
    /*
16107
    * TODO: Correct the error code; XML_SCHEMAP_COS_CT_EXTENDS_1_1 is used
16108
    * temporarily only.
16109
    */
16110
    /*
16111
    * SPEC (1) "If the {base type definition} is a complex type definition,
16112
    * then all of the following must be true:"
16113
    */
16114
0
    if (WXS_IS_COMPLEX(base)) {
16115
  /*
16116
  * SPEC (1.1) "The {final} of the {base type definition} must not
16117
  * contain extension."
16118
  */
16119
0
  if (base->flags & XML_SCHEMAS_TYPE_FINAL_EXTENSION) {
16120
0
      xmlSchemaPCustomErr(ctxt,
16121
0
    XML_SCHEMAP_COS_CT_EXTENDS_1_1,
16122
0
    WXS_BASIC_CAST type, NULL,
16123
0
    "The 'final' of the base type definition "
16124
0
    "contains 'extension'", NULL);
16125
0
      return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
16126
0
  }
16127
16128
  /*
16129
  * ATTENTION: The constrains (1.2) and (1.3) are not applied,
16130
  * since they are automatically satisfied through the
16131
  * inheriting mechanism.
16132
  * Note that even if redefining components, the inheriting mechanism
16133
  * is used.
16134
  */
16135
#if 0
16136
  /*
16137
  * SPEC (1.2) "Its {attribute uses} must be a subset of the {attribute
16138
  * uses}
16139
  * of the complex type definition itself, that is, for every attribute
16140
  * use in the {attribute uses} of the {base type definition}, there
16141
  * must be an attribute use in the {attribute uses} of the complex
16142
  * type definition itself whose {attribute declaration} has the same
16143
  * {name}, {target namespace} and {type definition} as its attribute
16144
  * declaration"
16145
  */
16146
  if (base->attrUses != NULL) {
16147
      int i, j, found;
16148
      xmlSchemaAttributeUsePtr use, buse;
16149
16150
      for (i = 0; i < (WXS_LIST_CAST base->attrUses)->nbItems; i ++) {
16151
    buse = (WXS_LIST_CAST base->attrUses)->items[i];
16152
    found = 0;
16153
    if (type->attrUses != NULL) {
16154
        use = (WXS_LIST_CAST type->attrUses)->items[j];
16155
        for (j = 0; j < (WXS_LIST_CAST type->attrUses)->nbItems; j ++)
16156
        {
16157
      if ((WXS_ATTRUSE_DECL_NAME(use) ==
16158
        WXS_ATTRUSE_DECL_NAME(buse)) &&
16159
          (WXS_ATTRUSE_DECL_TNS(use) ==
16160
        WXS_ATTRUSE_DECL_TNS(buse)) &&
16161
          (WXS_ATTRUSE_TYPEDEF(use) ==
16162
        WXS_ATTRUSE_TYPEDEF(buse))
16163
      {
16164
          found = 1;
16165
          break;
16166
      }
16167
        }
16168
    }
16169
    if (! found) {
16170
        xmlChar *str = NULL;
16171
16172
        xmlSchemaCustomErr(ACTXT_CAST ctxt,
16173
      XML_SCHEMAP_COS_CT_EXTENDS_1_2,
16174
      NULL, WXS_BASIC_CAST type,
16175
      /*
16176
      * TODO: The report does not indicate that also the
16177
      * type needs to be the same.
16178
      */
16179
      "This type is missing a matching correspondent "
16180
      "for its {base type}'s %s in its {attribute uses}",
16181
      xmlSchemaGetComponentDesignation(&str,
16182
          buse->children),
16183
      NULL);
16184
        FREE_AND_NULL(str)
16185
    }
16186
      }
16187
  }
16188
  /*
16189
  * SPEC (1.3) "If it has an {attribute wildcard}, the complex type
16190
  * definition must also have one, and the base type definition's
16191
  * {attribute  wildcard}'s {namespace constraint} must be a subset
16192
  * of the complex  type definition's {attribute wildcard}'s {namespace
16193
  * constraint}, as defined by Wildcard Subset ($3.10.6)."
16194
  */
16195
16196
  /*
16197
  * MAYBE TODO: Enable if ever needed. But this will be needed only
16198
  * if created the type via a schema construction API.
16199
  */
16200
  if (base->attributeWildcard != NULL) {
16201
      if (type->attributeWildcard == NULL) {
16202
    xmlChar *str = NULL;
16203
16204
    xmlSchemaCustomErr(ACTXT_CAST pctxt,
16205
        XML_SCHEMAP_COS_CT_EXTENDS_1_3,
16206
        NULL, type,
16207
        "The base %s has an attribute wildcard, "
16208
        "but this type is missing an attribute wildcard",
16209
        xmlSchemaGetComponentDesignation(&str, base));
16210
    FREE_AND_NULL(str)
16211
16212
      } else if (xmlSchemaCheckCOSNSSubset(
16213
    base->attributeWildcard, type->attributeWildcard))
16214
      {
16215
    xmlChar *str = NULL;
16216
16217
    xmlSchemaCustomErr(ACTXT_CAST pctxt,
16218
        XML_SCHEMAP_COS_CT_EXTENDS_1_3,
16219
        NULL, type,
16220
        "The attribute wildcard is not a valid "
16221
        "superset of the one in the base %s",
16222
        xmlSchemaGetComponentDesignation(&str, base));
16223
    FREE_AND_NULL(str)
16224
      }
16225
  }
16226
#endif
16227
  /*
16228
  * SPEC (1.4) "One of the following must be true:"
16229
  */
16230
0
  if ((type->contentTypeDef != NULL) &&
16231
0
      (type->contentTypeDef == base->contentTypeDef)) {
16232
      /*
16233
      * SPEC (1.4.1) "The {content type} of the {base type definition}
16234
      * and the {content type} of the complex type definition itself
16235
      * must be the same simple type definition"
16236
      * PASS
16237
      */
16238
0
  } else if ((type->contentType == XML_SCHEMA_CONTENT_EMPTY) &&
16239
0
      (base->contentType == XML_SCHEMA_CONTENT_EMPTY) ) {
16240
      /*
16241
      * SPEC (1.4.2) "The {content type} of both the {base type
16242
      * definition} and the complex type definition itself must
16243
      * be empty."
16244
      * PASS
16245
      */
16246
0
  } else {
16247
      /*
16248
      * SPEC (1.4.3) "All of the following must be true:"
16249
      */
16250
0
      if (type->subtypes == NULL) {
16251
    /*
16252
    * SPEC 1.4.3.1 The {content type} of the complex type
16253
    * definition itself must specify a particle.
16254
    */
16255
0
    xmlSchemaPCustomErr(ctxt,
16256
0
        XML_SCHEMAP_COS_CT_EXTENDS_1_1,
16257
0
        WXS_BASIC_CAST type, NULL,
16258
0
        "The content type must specify a particle", NULL);
16259
0
    return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
16260
0
      }
16261
      /*
16262
      * SPEC (1.4.3.2) "One of the following must be true:"
16263
      */
16264
0
      if (base->contentType == XML_SCHEMA_CONTENT_EMPTY) {
16265
    /*
16266
    * SPEC (1.4.3.2.1) "The {content type} of the {base type
16267
    * definition} must be empty.
16268
    * PASS
16269
    */
16270
0
      } else {
16271
    /*
16272
    * SPEC (1.4.3.2.2) "All of the following must be true:"
16273
    */
16274
0
    if ((type->contentType != base->contentType) ||
16275
0
        ((type->contentType != XML_SCHEMA_CONTENT_MIXED) &&
16276
0
        (type->contentType != XML_SCHEMA_CONTENT_ELEMENTS))) {
16277
        /*
16278
        * SPEC (1.4.3.2.2.1) "Both {content type}s must be mixed
16279
        * or both must be element-only."
16280
        */
16281
0
        xmlSchemaPCustomErr(ctxt,
16282
0
      XML_SCHEMAP_COS_CT_EXTENDS_1_1,
16283
0
      WXS_BASIC_CAST type, NULL,
16284
0
      "The content type of both, the type and its base "
16285
0
      "type, must either 'mixed' or 'element-only'", NULL);
16286
0
        return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
16287
0
    }
16288
    /*
16289
    * URGENT TODO SPEC (1.4.3.2.2.2) "The particle of the
16290
    * complex type definition must be a `valid extension`
16291
    * of the {base type definition}'s particle, as defined
16292
    * in Particle Valid (Extension) ($3.9.6)."
16293
    *
16294
    * NOTE that we won't check "Particle Valid (Extension)",
16295
    * since it is ensured by the derivation process in
16296
    * xmlSchemaTypeFixup(). We need to implement this when heading
16297
    * for a construction API
16298
    * TODO: !! This is needed to be checked if redefining a type !!
16299
    */
16300
0
      }
16301
      /*
16302
      * URGENT TODO (1.5)
16303
      */
16304
0
  }
16305
0
    } else {
16306
  /*
16307
  * SPEC (2) "If the {base type definition} is a simple type definition,
16308
  * then all of the following must be true:"
16309
  */
16310
0
  if (type->contentTypeDef != base) {
16311
      /*
16312
      * SPEC (2.1) "The {content type} must be the same simple type
16313
      * definition."
16314
      */
16315
0
      xmlSchemaPCustomErr(ctxt,
16316
0
    XML_SCHEMAP_COS_CT_EXTENDS_1_1,
16317
0
    WXS_BASIC_CAST type, NULL,
16318
0
    "The content type must be the simple base type", NULL);
16319
0
      return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
16320
0
  }
16321
0
  if (base->flags & XML_SCHEMAS_TYPE_FINAL_EXTENSION) {
16322
      /*
16323
      * SPEC (2.2) "The {final} of the {base type definition} must not
16324
      * contain extension"
16325
      * NOTE that this is the same as (1.1).
16326
      */
16327
0
      xmlSchemaPCustomErr(ctxt,
16328
0
    XML_SCHEMAP_COS_CT_EXTENDS_1_1,
16329
0
    WXS_BASIC_CAST type, NULL,
16330
0
    "The 'final' of the base type definition "
16331
0
    "contains 'extension'", NULL);
16332
0
      return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
16333
0
  }
16334
0
    }
16335
0
    return (0);
16336
0
}
16337
16338
/**
16339
 * xmlSchemaCheckDerivationOKRestriction:
16340
 * @ctxt:  the schema parser context
16341
 * @type:  the complex type definition
16342
 *
16343
 * (3.4.6) Constraints on Complex Type Definition Schema Components
16344
 * Schema Component Constraint:
16345
 * Derivation Valid (Restriction, Complex) (derivation-ok-restriction)
16346
 *
16347
 * STATUS:
16348
 *   missing:
16349
 *     (5.4.2) ???
16350
 *
16351
 * ATTENTION:
16352
 * In XML Schema 1.1 this will be:
16353
 * Validation Rule: Checking complex type subsumption
16354
 *
16355
 * Returns 0 if the constraints are satisfied, a positive
16356
 * error code if not and -1 if an internal error occurred.
16357
 */
16358
static int
16359
xmlSchemaCheckDerivationOKRestriction(xmlSchemaParserCtxtPtr ctxt,
16360
              xmlSchemaTypePtr type)
16361
0
{
16362
0
    xmlSchemaTypePtr base;
16363
16364
    /*
16365
    * TODO: Correct the error code; XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1 is used
16366
    * temporarily only.
16367
    */
16368
0
    base = type->baseType;
16369
0
    if (! WXS_IS_COMPLEX(base)) {
16370
0
  xmlSchemaCustomErr(ACTXT_CAST ctxt,
16371
0
      XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
16372
0
      type->node, WXS_BASIC_CAST type,
16373
0
      "The base type must be a complex type", NULL, NULL);
16374
0
  return(ctxt->err);
16375
0
    }
16376
0
    if (base->flags & XML_SCHEMAS_TYPE_FINAL_RESTRICTION) {
16377
  /*
16378
  * SPEC (1) "The {base type definition} must be a complex type
16379
  * definition whose {final} does not contain restriction."
16380
  */
16381
0
  xmlSchemaCustomErr(ACTXT_CAST ctxt,
16382
0
      XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
16383
0
      type->node, WXS_BASIC_CAST type,
16384
0
      "The 'final' of the base type definition "
16385
0
      "contains 'restriction'", NULL, NULL);
16386
0
  return (ctxt->err);
16387
0
    }
16388
    /*
16389
    * SPEC (2), (3) and (4)
16390
    * Those are handled in a separate function, since the
16391
    * same constraints are needed for redefinition of
16392
    * attribute groups as well.
16393
    */
16394
0
    if (xmlSchemaCheckDerivationOKRestriction2to4(ctxt,
16395
0
  XML_SCHEMA_ACTION_DERIVE,
16396
0
  WXS_BASIC_CAST type, WXS_BASIC_CAST base,
16397
0
  type->attrUses, base->attrUses,
16398
0
  type->attributeWildcard,
16399
0
  base->attributeWildcard) == -1)
16400
0
    {
16401
0
  return(-1);
16402
0
    }
16403
    /*
16404
    * SPEC (5) "One of the following must be true:"
16405
    */
16406
0
    if (base->builtInType == XML_SCHEMAS_ANYTYPE) {
16407
  /*
16408
  * SPEC (5.1) "The {base type definition} must be the
16409
  * `ur-type definition`."
16410
  * PASS
16411
  */
16412
0
    } else if ((type->contentType == XML_SCHEMA_CONTENT_SIMPLE) ||
16413
0
      (type->contentType == XML_SCHEMA_CONTENT_BASIC)) {
16414
  /*
16415
  * SPEC (5.2.1) "The {content type} of the complex type definition
16416
  * must be a simple type definition"
16417
  *
16418
  * SPEC (5.2.2) "One of the following must be true:"
16419
  */
16420
0
  if ((base->contentType == XML_SCHEMA_CONTENT_SIMPLE) ||
16421
0
      (base->contentType == XML_SCHEMA_CONTENT_BASIC))
16422
0
  {
16423
0
      int err;
16424
      /*
16425
      * SPEC (5.2.2.1) "The {content type} of the {base type
16426
      * definition} must be a simple type definition from which
16427
      * the {content type} is validly derived given the empty
16428
      * set as defined in Type Derivation OK (Simple) ($3.14.6)."
16429
      *
16430
      * ATTENTION TODO: This seems not needed if the type implicitly
16431
      * derived from the base type.
16432
      *
16433
      */
16434
0
      err = xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST ctxt,
16435
0
    type->contentTypeDef, base->contentTypeDef, 0);
16436
0
      if (err != 0) {
16437
0
    xmlChar *strA = NULL, *strB = NULL;
16438
16439
0
    if (err == -1)
16440
0
        return(-1);
16441
0
    xmlSchemaCustomErr(ACTXT_CAST ctxt,
16442
0
        XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
16443
0
        NULL, WXS_BASIC_CAST type,
16444
0
        "The {content type} %s is not validly derived from the "
16445
0
        "base type's {content type} %s",
16446
0
        xmlSchemaGetComponentDesignation(&strA,
16447
0
      type->contentTypeDef),
16448
0
        xmlSchemaGetComponentDesignation(&strB,
16449
0
      base->contentTypeDef));
16450
0
    FREE_AND_NULL(strA);
16451
0
    FREE_AND_NULL(strB);
16452
0
    return(ctxt->err);
16453
0
      }
16454
0
  } else if ((base->contentType == XML_SCHEMA_CONTENT_MIXED) &&
16455
0
      (xmlSchemaIsParticleEmptiable(
16456
0
    (xmlSchemaParticlePtr) base->subtypes))) {
16457
      /*
16458
      * SPEC (5.2.2.2) "The {base type definition} must be mixed
16459
      * and have a particle which is `emptiable` as defined in
16460
      * Particle Emptiable ($3.9.6)."
16461
      * PASS
16462
      */
16463
0
  } else {
16464
0
      xmlSchemaPCustomErr(ctxt,
16465
0
    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
16466
0
    WXS_BASIC_CAST type, NULL,
16467
0
    "The content type of the base type must be either "
16468
0
    "a simple type or 'mixed' and an emptiable particle", NULL);
16469
0
      return (ctxt->err);
16470
0
  }
16471
0
    } else if (type->contentType == XML_SCHEMA_CONTENT_EMPTY) {
16472
  /*
16473
  * SPEC (5.3.1) "The {content type} of the complex type itself must
16474
  * be empty"
16475
  */
16476
0
  if (base->contentType == XML_SCHEMA_CONTENT_EMPTY) {
16477
      /*
16478
      * SPEC (5.3.2.1) "The {content type} of the {base type
16479
      * definition} must also be empty."
16480
      * PASS
16481
      */
16482
0
  } else if (((base->contentType == XML_SCHEMA_CONTENT_ELEMENTS) ||
16483
0
      (base->contentType == XML_SCHEMA_CONTENT_MIXED)) &&
16484
0
      xmlSchemaIsParticleEmptiable(
16485
0
    (xmlSchemaParticlePtr) base->subtypes)) {
16486
      /*
16487
      * SPEC (5.3.2.2) "The {content type} of the {base type
16488
      * definition} must be elementOnly or mixed and have a particle
16489
      * which is `emptiable` as defined in Particle Emptiable ($3.9.6)."
16490
      * PASS
16491
      */
16492
0
  } else {
16493
0
      xmlSchemaPCustomErr(ctxt,
16494
0
    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
16495
0
    WXS_BASIC_CAST type, NULL,
16496
0
    "The content type of the base type must be either "
16497
0
    "empty or 'mixed' (or 'elements-only') and an emptiable "
16498
0
    "particle", NULL);
16499
0
      return (ctxt->err);
16500
0
  }
16501
0
    } else if ((type->contentType == XML_SCHEMA_CONTENT_ELEMENTS) ||
16502
0
  WXS_HAS_MIXED_CONTENT(type)) {
16503
  /*
16504
  * SPEC (5.4.1.1) "The {content type} of the complex type definition
16505
  * itself must be element-only"
16506
  */
16507
0
  if (WXS_HAS_MIXED_CONTENT(type) && (! WXS_HAS_MIXED_CONTENT(base))) {
16508
      /*
16509
      * SPEC (5.4.1.2) "The {content type} of the complex type
16510
      * definition itself and of the {base type definition} must be
16511
      * mixed"
16512
      */
16513
0
      xmlSchemaPCustomErr(ctxt,
16514
0
    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
16515
0
    WXS_BASIC_CAST type, NULL,
16516
0
    "If the content type is 'mixed', then the content type of the "
16517
0
    "base type must also be 'mixed'", NULL);
16518
0
      return (ctxt->err);
16519
0
  }
16520
  /*
16521
  * SPEC (5.4.2) "The particle of the complex type definition itself
16522
  * must be a `valid restriction` of the particle of the {content
16523
  * type} of the {base type definition} as defined in Particle Valid
16524
  * (Restriction) ($3.9.6).
16525
  *
16526
  * URGENT TODO: (5.4.2)
16527
  */
16528
0
    } else {
16529
0
  xmlSchemaPCustomErr(ctxt,
16530
0
      XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
16531
0
      WXS_BASIC_CAST type, NULL,
16532
0
      "The type is not a valid restriction of its base type", NULL);
16533
0
  return (ctxt->err);
16534
0
    }
16535
0
    return (0);
16536
0
}
16537
16538
/**
16539
 * xmlSchemaCheckCTComponent:
16540
 * @ctxt:  the schema parser context
16541
 * @type:  the complex type definition
16542
 *
16543
 * (3.4.6) Constraints on Complex Type Definition Schema Components
16544
 *
16545
 * Returns 0 if the constraints are satisfied, a positive
16546
 * error code if not and -1 if an internal error occurred.
16547
 */
16548
static int
16549
xmlSchemaCheckCTComponent(xmlSchemaParserCtxtPtr ctxt,
16550
        xmlSchemaTypePtr type)
16551
0
{
16552
0
    int ret;
16553
    /*
16554
    * Complex Type Definition Properties Correct
16555
    */
16556
0
    ret = xmlSchemaCheckCTPropsCorrect(ctxt, type);
16557
0
    if (ret != 0)
16558
0
  return (ret);
16559
0
    if (WXS_IS_EXTENSION(type))
16560
0
  ret = xmlSchemaCheckCOSCTExtends(ctxt, type);
16561
0
    else
16562
0
  ret = xmlSchemaCheckDerivationOKRestriction(ctxt, type);
16563
0
    return (ret);
16564
0
}
16565
16566
/**
16567
 * xmlSchemaCheckSRCCT:
16568
 * @ctxt:  the schema parser context
16569
 * @type:  the complex type definition
16570
 *
16571
 * (3.4.3) Constraints on XML Representations of Complex Type Definitions:
16572
 * Schema Representation Constraint:
16573
 * Complex Type Definition Representation OK (src-ct)
16574
 *
16575
 * Returns 0 if the constraints are satisfied, a positive
16576
 * error code if not and -1 if an internal error occurred.
16577
 */
16578
static int
16579
xmlSchemaCheckSRCCT(xmlSchemaParserCtxtPtr ctxt,
16580
        xmlSchemaTypePtr type)
16581
0
{
16582
0
    xmlSchemaTypePtr base;
16583
0
    int ret = 0;
16584
16585
    /*
16586
    * TODO: Adjust the error codes here, as I used
16587
    * XML_SCHEMAP_SRC_CT_1 only yet.
16588
    */
16589
0
    base = type->baseType;
16590
0
    if (! WXS_HAS_SIMPLE_CONTENT(type)) {
16591
  /*
16592
  * 1 If the <complexContent> alternative is chosen, the type definition
16593
  * `resolved` to by the `actual value` of the base [attribute]
16594
  * must be a complex type definition;
16595
  */
16596
0
  if (! WXS_IS_COMPLEX(base)) {
16597
0
      xmlChar *str = NULL;
16598
0
      xmlSchemaPCustomErr(ctxt,
16599
0
    XML_SCHEMAP_SRC_CT_1,
16600
0
    WXS_BASIC_CAST type, type->node,
16601
0
    "If using <complexContent>, the base type is expected to be "
16602
0
    "a complex type. The base type '%s' is a simple type",
16603
0
    xmlSchemaFormatQName(&str, base->targetNamespace,
16604
0
    base->name));
16605
0
      FREE_AND_NULL(str)
16606
0
      return (XML_SCHEMAP_SRC_CT_1);
16607
0
  }
16608
0
    } else {
16609
  /*
16610
  * SPEC
16611
  * 2 If the <simpleContent> alternative is chosen, all of the
16612
  * following must be true:
16613
  * 2.1 The type definition `resolved` to by the `actual value` of the
16614
  * base [attribute] must be one of the following:
16615
  */
16616
0
  if (WXS_IS_SIMPLE(base)) {
16617
0
      if (WXS_IS_EXTENSION(type) == 0) {
16618
0
    xmlChar *str = NULL;
16619
    /*
16620
    * 2.1.3 only if the <extension> alternative is also
16621
    * chosen, a simple type definition.
16622
    */
16623
    /* TODO: Change error code to ..._SRC_CT_2_1_3. */
16624
0
    xmlSchemaPCustomErr(ctxt,
16625
0
        XML_SCHEMAP_SRC_CT_1,
16626
0
        WXS_BASIC_CAST type, NULL,
16627
0
        "If using <simpleContent> and <restriction>, the base "
16628
0
        "type must be a complex type. The base type '%s' is "
16629
0
        "a simple type",
16630
0
        xmlSchemaFormatQName(&str, base->targetNamespace,
16631
0
      base->name));
16632
0
    FREE_AND_NULL(str)
16633
0
    return (XML_SCHEMAP_SRC_CT_1);
16634
0
      }
16635
0
  } else {
16636
      /* Base type is a complex type. */
16637
0
      if ((base->contentType == XML_SCHEMA_CONTENT_SIMPLE) ||
16638
0
    (base->contentType == XML_SCHEMA_CONTENT_BASIC)) {
16639
    /*
16640
    * 2.1.1 a complex type definition whose {content type} is a
16641
    * simple type definition;
16642
    * PASS
16643
    */
16644
0
    if (base->contentTypeDef == NULL) {
16645
0
        xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_INTERNAL,
16646
0
      WXS_BASIC_CAST type, NULL,
16647
0
      "Internal error: xmlSchemaCheckSRCCT, "
16648
0
      "'%s', base type has no content type",
16649
0
      type->name);
16650
0
        return (-1);
16651
0
    }
16652
0
      } else if ((base->contentType == XML_SCHEMA_CONTENT_MIXED) &&
16653
0
    (WXS_IS_RESTRICTION(type))) {
16654
16655
    /*
16656
    * 2.1.2 only if the <restriction> alternative is also
16657
    * chosen, a complex type definition whose {content type}
16658
    * is mixed and a particle emptiable.
16659
    */
16660
0
    if (! xmlSchemaIsParticleEmptiable(
16661
0
        (xmlSchemaParticlePtr) base->subtypes)) {
16662
0
        ret = XML_SCHEMAP_SRC_CT_1;
16663
0
    } else
16664
        /*
16665
        * Attention: at this point the <simpleType> child is in
16666
        * ->contentTypeDef (put there during parsing).
16667
        */
16668
0
        if (type->contentTypeDef == NULL) {
16669
0
        xmlChar *str = NULL;
16670
        /*
16671
        * 2.2 If clause 2.1.2 above is satisfied, then there
16672
        * must be a <simpleType> among the [children] of
16673
        * <restriction>.
16674
        */
16675
        /* TODO: Change error code to ..._SRC_CT_2_2. */
16676
0
        xmlSchemaPCustomErr(ctxt,
16677
0
      XML_SCHEMAP_SRC_CT_1,
16678
0
      WXS_BASIC_CAST type, NULL,
16679
0
      "A <simpleType> is expected among the children "
16680
0
      "of <restriction>, if <simpleContent> is used and "
16681
0
      "the base type '%s' is a complex type",
16682
0
      xmlSchemaFormatQName(&str, base->targetNamespace,
16683
0
      base->name));
16684
0
        FREE_AND_NULL(str)
16685
0
        return (XML_SCHEMAP_SRC_CT_1);
16686
0
    }
16687
0
      } else {
16688
0
    ret = XML_SCHEMAP_SRC_CT_1;
16689
0
      }
16690
0
  }
16691
0
  if (ret > 0) {
16692
0
      xmlChar *str = NULL;
16693
0
      if (WXS_IS_RESTRICTION(type)) {
16694
0
    xmlSchemaPCustomErr(ctxt,
16695
0
        XML_SCHEMAP_SRC_CT_1,
16696
0
        WXS_BASIC_CAST type, NULL,
16697
0
        "If <simpleContent> and <restriction> is used, the "
16698
0
        "base type must be a simple type or a complex type with "
16699
0
        "mixed content and particle emptiable. The base type "
16700
0
        "'%s' is none of those",
16701
0
        xmlSchemaFormatQName(&str, base->targetNamespace,
16702
0
        base->name));
16703
0
      } else {
16704
0
    xmlSchemaPCustomErr(ctxt,
16705
0
        XML_SCHEMAP_SRC_CT_1,
16706
0
        WXS_BASIC_CAST type, NULL,
16707
0
        "If <simpleContent> and <extension> is used, the "
16708
0
        "base type must be a simple type. The base type '%s' "
16709
0
        "is a complex type",
16710
0
        xmlSchemaFormatQName(&str, base->targetNamespace,
16711
0
        base->name));
16712
0
      }
16713
0
      FREE_AND_NULL(str)
16714
0
  }
16715
0
    }
16716
    /*
16717
    * SPEC (3) "The corresponding complex type definition component must
16718
    * satisfy the conditions set out in Constraints on Complex Type
16719
    * Definition Schema Components ($3.4.6);"
16720
    * NOTE (3) will be done in xmlSchemaTypeFixup().
16721
    */
16722
    /*
16723
    * SPEC (4) If clause 2.2.1 or clause 2.2.2 in the correspondence specification
16724
    * above for {attribute wildcard} is satisfied, the intensional
16725
    * intersection must be expressible, as defined in Attribute Wildcard
16726
    * Intersection ($3.10.6).
16727
    * NOTE (4) is done in xmlSchemaFixupTypeAttributeUses().
16728
    */
16729
0
    return (ret);
16730
0
}
16731
16732
#ifdef ENABLE_PARTICLE_RESTRICTION
16733
/**
16734
 * xmlSchemaCheckParticleRangeOK:
16735
 * @ctxt:  the schema parser context
16736
 * @type:  the complex type definition
16737
 *
16738
 * (3.9.6) Constraints on Particle Schema Components
16739
 * Schema Component Constraint:
16740
 * Occurrence Range OK (range-ok)
16741
 *
16742
 * STATUS: complete
16743
 *
16744
 * Returns 0 if the constraints are satisfied, a positive
16745
 * error code if not and -1 if an internal error occurred.
16746
 */
16747
static int
16748
xmlSchemaCheckParticleRangeOK(int rmin, int rmax,
16749
            int bmin, int bmax)
16750
{
16751
    if (rmin < bmin)
16752
  return (1);
16753
    if ((bmax != UNBOUNDED) &&
16754
  (rmax > bmax))
16755
  return (1);
16756
    return (0);
16757
}
16758
16759
/**
16760
 * xmlSchemaCheckRCaseNameAndTypeOK:
16761
 * @ctxt:  the schema parser context
16762
 * @r: the restricting element declaration particle
16763
 * @b: the base element declaration particle
16764
 *
16765
 * (3.9.6) Constraints on Particle Schema Components
16766
 * Schema Component Constraint:
16767
 * Particle Restriction OK (Elt:Elt -- NameAndTypeOK)
16768
 * (rcase-NameAndTypeOK)
16769
 *
16770
 * STATUS:
16771
 *   MISSING (3.2.3)
16772
 *   CLARIFY: (3.2.2)
16773
 *
16774
 * Returns 0 if the constraints are satisfied, a positive
16775
 * error code if not and -1 if an internal error occurred.
16776
 */
16777
static int
16778
xmlSchemaCheckRCaseNameAndTypeOK(xmlSchemaParserCtxtPtr ctxt,
16779
         xmlSchemaParticlePtr r,
16780
         xmlSchemaParticlePtr b)
16781
{
16782
    xmlSchemaElementPtr elemR, elemB;
16783
16784
    /* TODO: Error codes (rcase-NameAndTypeOK). */
16785
    elemR = (xmlSchemaElementPtr) r->children;
16786
    elemB = (xmlSchemaElementPtr) b->children;
16787
    /*
16788
    * SPEC (1) "The declarations' {name}s and {target namespace}s are
16789
    * the same."
16790
    */
16791
    if ((elemR != elemB) &&
16792
  ((! xmlStrEqual(elemR->name, elemB->name)) ||
16793
  (! xmlStrEqual(elemR->targetNamespace, elemB->targetNamespace))))
16794
  return (1);
16795
    /*
16796
    * SPEC (2) "R's occurrence range is a valid restriction of B's
16797
    * occurrence range as defined by Occurrence Range OK ($3.9.6)."
16798
    */
16799
    if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
16800
      b->minOccurs, b->maxOccurs) != 0)
16801
  return (1);
16802
    /*
16803
    * SPEC (3.1) "Both B's declaration's {scope} and R's declaration's
16804
    * {scope} are global."
16805
    */
16806
    if (elemR == elemB)
16807
  return (0);
16808
    /*
16809
    * SPEC (3.2.1) "Either B's {nillable} is true or R's {nillable} is false."
16810
    */
16811
    if (((elemB->flags & XML_SCHEMAS_ELEM_NILLABLE) == 0) &&
16812
  (elemR->flags & XML_SCHEMAS_ELEM_NILLABLE))
16813
   return (1);
16814
    /*
16815
    * SPEC (3.2.2) "either B's declaration's {value constraint} is absent,
16816
    * or is not fixed, or R's declaration's {value constraint} is fixed
16817
    * with the same value."
16818
    */
16819
    if ((elemB->value != NULL) && (elemB->flags & XML_SCHEMAS_ELEM_FIXED) &&
16820
  ((elemR->value == NULL) ||
16821
   ((elemR->flags & XML_SCHEMAS_ELEM_FIXED) == 0) ||
16822
   /* TODO: Equality of the initial value or normalized or canonical? */
16823
   (! xmlStrEqual(elemR->value, elemB->value))))
16824
   return (1);
16825
    /*
16826
    * TODO: SPEC (3.2.3) "R's declaration's {identity-constraint
16827
    * definitions} is a subset of B's declaration's {identity-constraint
16828
    * definitions}, if any."
16829
    */
16830
    if (elemB->idcs != NULL) {
16831
  /* TODO */
16832
    }
16833
    /*
16834
    * SPEC (3.2.4) "R's declaration's {disallowed substitutions} is a
16835
    * superset of B's declaration's {disallowed substitutions}."
16836
    */
16837
    if (((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) &&
16838
   ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) == 0)) ||
16839
  ((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) &&
16840
   ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) == 0)) ||
16841
  ((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION) &&
16842
   ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION) == 0)))
16843
   return (1);
16844
    /*
16845
    * SPEC (3.2.5) "R's {type definition} is validly derived given
16846
    * {extension, list, union} from B's {type definition}"
16847
    *
16848
    * BADSPEC TODO: What's the point of adding "list" and "union" to the
16849
    * set, if the corresponding constraints handle "restriction" and
16850
    * "extension" only?
16851
    *
16852
    */
16853
    {
16854
  int set = 0;
16855
16856
  set |= SUBSET_EXTENSION;
16857
  set |= SUBSET_LIST;
16858
  set |= SUBSET_UNION;
16859
  if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST ctxt, elemR->subtypes,
16860
      elemB->subtypes, set) != 0)
16861
      return (1);
16862
    }
16863
    return (0);
16864
}
16865
16866
/**
16867
 * xmlSchemaCheckRCaseNSCompat:
16868
 * @ctxt:  the schema parser context
16869
 * @r: the restricting element declaration particle
16870
 * @b: the base wildcard particle
16871
 *
16872
 * (3.9.6) Constraints on Particle Schema Components
16873
 * Schema Component Constraint:
16874
 * Particle Derivation OK (Elt:Any -- NSCompat)
16875
 * (rcase-NSCompat)
16876
 *
16877
 * STATUS: complete
16878
 *
16879
 * Returns 0 if the constraints are satisfied, a positive
16880
 * error code if not and -1 if an internal error occurred.
16881
 */
16882
static int
16883
xmlSchemaCheckRCaseNSCompat(xmlSchemaParserCtxtPtr ctxt,
16884
          xmlSchemaParticlePtr r,
16885
          xmlSchemaParticlePtr b)
16886
{
16887
    /* TODO:Error codes (rcase-NSCompat). */
16888
    /*
16889
    * SPEC "For an element declaration particle to be a `valid restriction`
16890
    * of a wildcard particle all of the following must be true:"
16891
    *
16892
    * SPEC (1) "The element declaration's {target namespace} is `valid`
16893
    * with respect to the wildcard's {namespace constraint} as defined by
16894
    * Wildcard allows Namespace Name ($3.10.4)."
16895
    */
16896
    if (xmlSchemaCheckCVCWildcardNamespace((xmlSchemaWildcardPtr) b->children,
16897
  ((xmlSchemaElementPtr) r->children)->targetNamespace) != 0)
16898
  return (1);
16899
    /*
16900
    * SPEC (2) "R's occurrence range is a valid restriction of B's
16901
    * occurrence range as defined by Occurrence Range OK ($3.9.6)."
16902
    */
16903
    if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
16904
      b->minOccurs, b->maxOccurs) != 0)
16905
  return (1);
16906
16907
    return (0);
16908
}
16909
16910
/**
16911
 * xmlSchemaCheckRCaseRecurseAsIfGroup:
16912
 * @ctxt:  the schema parser context
16913
 * @r: the restricting element declaration particle
16914
 * @b: the base model group particle
16915
 *
16916
 * (3.9.6) Constraints on Particle Schema Components
16917
 * Schema Component Constraint:
16918
 * Particle Derivation OK (Elt:All/Choice/Sequence -- RecurseAsIfGroup)
16919
 * (rcase-RecurseAsIfGroup)
16920
 *
16921
 * STATUS: TODO
16922
 *
16923
 * Returns 0 if the constraints are satisfied, a positive
16924
 * error code if not and -1 if an internal error occurred.
16925
 */
16926
static int
16927
xmlSchemaCheckRCaseRecurseAsIfGroup(xmlSchemaParserCtxtPtr ctxt,
16928
            xmlSchemaParticlePtr r,
16929
            xmlSchemaParticlePtr b)
16930
{
16931
    /* TODO: Error codes (rcase-RecurseAsIfGroup). */
16932
    TODO
16933
    return (0);
16934
}
16935
16936
/**
16937
 * xmlSchemaCheckRCaseNSSubset:
16938
 * @ctxt:  the schema parser context
16939
 * @r: the restricting wildcard particle
16940
 * @b: the base wildcard particle
16941
 *
16942
 * (3.9.6) Constraints on Particle Schema Components
16943
 * Schema Component Constraint:
16944
 * Particle Derivation OK (Any:Any -- NSSubset)
16945
 * (rcase-NSSubset)
16946
 *
16947
 * STATUS: complete
16948
 *
16949
 * Returns 0 if the constraints are satisfied, a positive
16950
 * error code if not and -1 if an internal error occurred.
16951
 */
16952
static int
16953
xmlSchemaCheckRCaseNSSubset(xmlSchemaParserCtxtPtr ctxt,
16954
            xmlSchemaParticlePtr r,
16955
            xmlSchemaParticlePtr b,
16956
            int isAnyTypeBase)
16957
{
16958
    /* TODO: Error codes (rcase-NSSubset). */
16959
    /*
16960
    * SPEC (1) "R's occurrence range is a valid restriction of B's
16961
    * occurrence range as defined by Occurrence Range OK ($3.9.6)."
16962
    */
16963
    if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
16964
      b->minOccurs, b->maxOccurs))
16965
  return (1);
16966
    /*
16967
    * SPEC (2) "R's {namespace constraint} must be an intensional subset
16968
    * of B's {namespace constraint} as defined by Wildcard Subset ($3.10.6)."
16969
    */
16970
    if (xmlSchemaCheckCOSNSSubset((xmlSchemaWildcardPtr) r->children,
16971
  (xmlSchemaWildcardPtr) b->children))
16972
  return (1);
16973
    /*
16974
    * SPEC (3) "Unless B is the content model wildcard of the `ur-type
16975
    * definition`, R's {process contents} must be identical to or stronger
16976
    * than B's {process contents}, where strict is stronger than lax is
16977
    * stronger than skip."
16978
    */
16979
    if (! isAnyTypeBase) {
16980
  if ( ((xmlSchemaWildcardPtr) r->children)->processContents <
16981
      ((xmlSchemaWildcardPtr) b->children)->processContents)
16982
      return (1);
16983
    }
16984
16985
    return (0);
16986
}
16987
16988
/**
16989
 * xmlSchemaCheckCOSParticleRestrict:
16990
 * @ctxt:  the schema parser context
16991
 * @type:  the complex type definition
16992
 *
16993
 * (3.9.6) Constraints on Particle Schema Components
16994
 * Schema Component Constraint:
16995
 * Particle Valid (Restriction) (cos-particle-restrict)
16996
 *
16997
 * STATUS: TODO
16998
 *
16999
 * Returns 0 if the constraints are satisfied, a positive
17000
 * error code if not and -1 if an internal error occurred.
17001
 */
17002
static int
17003
xmlSchemaCheckCOSParticleRestrict(xmlSchemaParserCtxtPtr ctxt,
17004
          xmlSchemaParticlePtr r,
17005
          xmlSchemaParticlePtr b)
17006
{
17007
    int ret = 0;
17008
17009
    /*part = WXS_TYPE_PARTICLE(type);
17010
    basePart = WXS_TYPE_PARTICLE(base);
17011
    */
17012
17013
    TODO
17014
17015
    /*
17016
    * SPEC (1) "They are the same particle."
17017
    */
17018
    if (r == b)
17019
  return (0);
17020
17021
17022
    return (0);
17023
}
17024
17025
#if 0
17026
/**
17027
 * xmlSchemaCheckRCaseNSRecurseCheckCardinality:
17028
 * @ctxt:  the schema parser context
17029
 * @r: the model group particle
17030
 * @b: the base wildcard particle
17031
 *
17032
 * (3.9.6) Constraints on Particle Schema Components
17033
 * Schema Component Constraint:
17034
 * Particle Derivation OK (All/Choice/Sequence:Any --
17035
 *                         NSRecurseCheckCardinality)
17036
 * (rcase-NSRecurseCheckCardinality)
17037
 *
17038
 * STATUS: TODO: subst-groups
17039
 *
17040
 * Returns 0 if the constraints are satisfied, a positive
17041
 * error code if not and -1 if an internal error occurred.
17042
 */
17043
static int
17044
xmlSchemaCheckRCaseNSRecurseCheckCardinality(xmlSchemaParserCtxtPtr ctxt,
17045
               xmlSchemaParticlePtr r,
17046
               xmlSchemaParticlePtr b)
17047
{
17048
    xmlSchemaParticlePtr part;
17049
    /* TODO: Error codes (rcase-NSRecurseCheckCardinality). */
17050
    if ((r->children == NULL) || (r->children->children == NULL))
17051
  return (-1);
17052
    /*
17053
    * SPEC "For a group particle to be a `valid restriction` of a
17054
    * wildcard particle..."
17055
    *
17056
    * SPEC (1) "Every member of the {particles} of the group is a `valid
17057
    * restriction` of the wildcard as defined by
17058
    * Particle Valid (Restriction) ($3.9.6)."
17059
    */
17060
    part = (xmlSchemaParticlePtr) r->children->children;
17061
    do {
17062
  if (xmlSchemaCheckCOSParticleRestrict(ctxt, part, b))
17063
      return (1);
17064
  part = (xmlSchemaParticlePtr) part->next;
17065
    } while (part != NULL);
17066
    /*
17067
    * SPEC (2) "The effective total range of the group [...] is a
17068
    * valid restriction of B's occurrence range as defined by
17069
    * Occurrence Range OK ($3.9.6)."
17070
    */
17071
    if (xmlSchemaCheckParticleRangeOK(
17072
      xmlSchemaGetParticleTotalRangeMin(r),
17073
      xmlSchemaGetParticleTotalRangeMax(r),
17074
      b->minOccurs, b->maxOccurs) != 0)
17075
  return (1);
17076
    return (0);
17077
}
17078
#endif
17079
17080
/**
17081
 * xmlSchemaCheckRCaseRecurse:
17082
 * @ctxt:  the schema parser context
17083
 * @r: the <all> or <sequence> model group particle
17084
 * @b: the base <all> or <sequence> model group particle
17085
 *
17086
 * (3.9.6) Constraints on Particle Schema Components
17087
 * Schema Component Constraint:
17088
 * Particle Derivation OK (All:All,Sequence:Sequence --
17089
                           Recurse)
17090
 * (rcase-Recurse)
17091
 *
17092
 * STATUS:  ?
17093
 * TODO: subst-groups
17094
 *
17095
 * Returns 0 if the constraints are satisfied, a positive
17096
 * error code if not and -1 if an internal error occurred.
17097
 */
17098
static int
17099
xmlSchemaCheckRCaseRecurse(xmlSchemaParserCtxtPtr ctxt,
17100
         xmlSchemaParticlePtr r,
17101
         xmlSchemaParticlePtr b)
17102
{
17103
    /* xmlSchemaParticlePtr part; */
17104
    /* TODO: Error codes (rcase-Recurse). */
17105
    if ((r->children == NULL) || (b->children == NULL) ||
17106
  (r->children->type != b->children->type))
17107
  return (-1);
17108
    /*
17109
    * SPEC "For an all or sequence group particle to be a `valid
17110
    * restriction` of another group particle with the same {compositor}..."
17111
    *
17112
    * SPEC (1) "R's occurrence range is a valid restriction of B's
17113
    * occurrence range as defined by Occurrence Range OK ($3.9.6)."
17114
    */
17115
    if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
17116
      b->minOccurs, b->maxOccurs))
17117
  return (1);
17118
17119
17120
    return (0);
17121
}
17122
17123
#endif
17124
17125
#define FACET_RESTR_MUTUAL_ERR(fac1, fac2) \
17126
0
    xmlSchemaPCustomErrExt(pctxt,      \
17127
0
  XML_SCHEMAP_INVALID_FACET_VALUE, \
17128
0
  WXS_BASIC_CAST fac1, fac1->node, \
17129
0
  "It is an error for both '%s' and '%s' to be specified on the "\
17130
0
  "same type definition", \
17131
0
  BAD_CAST xmlSchemaFacetTypeToString(fac1->type), \
17132
0
  BAD_CAST xmlSchemaFacetTypeToString(fac2->type), NULL);
17133
17134
#define FACET_RESTR_ERR(fac1, msg) \
17135
0
    xmlSchemaPCustomErr(pctxt,      \
17136
0
  XML_SCHEMAP_INVALID_FACET_VALUE, \
17137
0
  WXS_BASIC_CAST fac1, fac1->node, \
17138
0
  msg, NULL);
17139
17140
#define FACET_RESTR_FIXED_ERR(fac) \
17141
0
    xmlSchemaPCustomErr(pctxt, \
17142
0
  XML_SCHEMAP_INVALID_FACET_VALUE, \
17143
0
  WXS_BASIC_CAST fac, fac->node, \
17144
0
  "The base type's facet is 'fixed', thus the value must not " \
17145
0
  "differ", NULL);
17146
17147
static void
17148
xmlSchemaDeriveFacetErr(xmlSchemaParserCtxtPtr pctxt,
17149
      xmlSchemaFacetPtr facet1,
17150
      xmlSchemaFacetPtr facet2,
17151
      int lessGreater,
17152
      int orEqual,
17153
      int ofBase)
17154
0
{
17155
0
    xmlChar *msg = NULL;
17156
17157
0
    msg = xmlStrdup(BAD_CAST "'");
17158
0
    msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facet1->type));
17159
0
    msg = xmlStrcat(msg, BAD_CAST "' has to be");
17160
0
    if (lessGreater == 0)
17161
0
  msg = xmlStrcat(msg, BAD_CAST " equal to");
17162
0
    if (lessGreater == 1)
17163
0
  msg = xmlStrcat(msg, BAD_CAST " greater than");
17164
0
    else
17165
0
  msg = xmlStrcat(msg, BAD_CAST " less than");
17166
17167
0
    if (orEqual)
17168
0
  msg = xmlStrcat(msg, BAD_CAST " or equal to");
17169
0
    msg = xmlStrcat(msg, BAD_CAST " '");
17170
0
    msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facet2->type));
17171
0
    if (ofBase)
17172
0
  msg = xmlStrcat(msg, BAD_CAST "' of the base type");
17173
0
    else
17174
0
  msg = xmlStrcat(msg, BAD_CAST "'");
17175
17176
0
    xmlSchemaPCustomErr(pctxt,
17177
0
  XML_SCHEMAP_INVALID_FACET_VALUE,
17178
0
  WXS_BASIC_CAST facet1, NULL,
17179
0
  (const char *) msg, NULL);
17180
17181
0
    if (msg != NULL)
17182
0
  xmlFree(msg);
17183
0
}
17184
17185
/*
17186
* xmlSchemaDeriveAndValidateFacets:
17187
*
17188
* Schema Component Constraint: Simple Type Restriction (Facets)
17189
* (st-restrict-facets)
17190
*/
17191
static int
17192
xmlSchemaDeriveAndValidateFacets(xmlSchemaParserCtxtPtr pctxt,
17193
         xmlSchemaTypePtr type)
17194
0
{
17195
0
    xmlSchemaTypePtr base = type->baseType;
17196
0
    xmlSchemaFacetLinkPtr link, cur, last = NULL;
17197
0
    xmlSchemaFacetPtr facet, bfacet,
17198
0
  flength = NULL, ftotdig = NULL, ffracdig = NULL,
17199
0
  fmaxlen = NULL, fminlen = NULL, /* facets of the current type */
17200
0
  fmininc = NULL, fmaxinc = NULL,
17201
0
  fminexc = NULL, fmaxexc = NULL,
17202
0
  bflength = NULL, bftotdig = NULL, bffracdig = NULL,
17203
0
  bfmaxlen = NULL, bfminlen = NULL, /* facets of the base type */
17204
0
  bfmininc = NULL, bfmaxinc = NULL,
17205
0
  bfminexc = NULL, bfmaxexc = NULL;
17206
0
    int res; /* err = 0, fixedErr; */
17207
17208
    /*
17209
    * SPEC st-restrict-facets 1:
17210
    * "The {variety} of R is the same as that of B."
17211
    */
17212
    /*
17213
    * SPEC st-restrict-facets 2:
17214
    * "If {variety} is atomic, the {primitive type definition}
17215
    * of R is the same as that of B."
17216
    *
17217
    * NOTE: we leave 1 & 2 out for now, since this will be
17218
    * satisfied by the derivation process.
17219
    * CONSTRUCTION TODO: Maybe needed if using a construction API.
17220
    */
17221
    /*
17222
    * SPEC st-restrict-facets 3:
17223
    * "The {facets} of R are the union of S and the {facets}
17224
    * of B, eliminating duplicates. To eliminate duplicates,
17225
    * when a facet of the same kind occurs in both S and the
17226
    * {facets} of B, the one in the {facets} of B is not
17227
    * included, with the exception of enumeration and pattern
17228
    * facets, for which multiple occurrences with distinct values
17229
    * are allowed."
17230
    */
17231
17232
0
    if ((type->facetSet == NULL) && (base->facetSet == NULL))
17233
0
  return (0);
17234
17235
0
    last = type->facetSet;
17236
0
    if (last != NULL)
17237
0
  while (last->next != NULL)
17238
0
      last = last->next;
17239
17240
0
    for (cur = type->facetSet; cur != NULL; cur = cur->next) {
17241
0
  facet = cur->facet;
17242
0
  switch (facet->type) {
17243
0
      case XML_SCHEMA_FACET_LENGTH:
17244
0
    flength = facet; break;
17245
0
      case XML_SCHEMA_FACET_MINLENGTH:
17246
0
    fminlen = facet; break;
17247
0
      case XML_SCHEMA_FACET_MININCLUSIVE:
17248
0
    fmininc = facet; break;
17249
0
      case XML_SCHEMA_FACET_MINEXCLUSIVE:
17250
0
    fminexc = facet; break;
17251
0
      case XML_SCHEMA_FACET_MAXLENGTH:
17252
0
    fmaxlen = facet; break;
17253
0
      case XML_SCHEMA_FACET_MAXINCLUSIVE:
17254
0
    fmaxinc = facet; break;
17255
0
      case XML_SCHEMA_FACET_MAXEXCLUSIVE:
17256
0
    fmaxexc = facet; break;
17257
0
      case XML_SCHEMA_FACET_TOTALDIGITS:
17258
0
    ftotdig = facet; break;
17259
0
      case XML_SCHEMA_FACET_FRACTIONDIGITS:
17260
0
    ffracdig = facet; break;
17261
0
      default:
17262
0
    break;
17263
0
  }
17264
0
    }
17265
0
    for (cur = base->facetSet; cur != NULL; cur = cur->next) {
17266
0
  facet = cur->facet;
17267
0
  switch (facet->type) {
17268
0
      case XML_SCHEMA_FACET_LENGTH:
17269
0
    bflength = facet; break;
17270
0
      case XML_SCHEMA_FACET_MINLENGTH:
17271
0
    bfminlen = facet; break;
17272
0
      case XML_SCHEMA_FACET_MININCLUSIVE:
17273
0
    bfmininc = facet; break;
17274
0
      case XML_SCHEMA_FACET_MINEXCLUSIVE:
17275
0
    bfminexc = facet; break;
17276
0
      case XML_SCHEMA_FACET_MAXLENGTH:
17277
0
    bfmaxlen = facet; break;
17278
0
      case XML_SCHEMA_FACET_MAXINCLUSIVE:
17279
0
    bfmaxinc = facet; break;
17280
0
      case XML_SCHEMA_FACET_MAXEXCLUSIVE:
17281
0
    bfmaxexc = facet; break;
17282
0
      case XML_SCHEMA_FACET_TOTALDIGITS:
17283
0
    bftotdig = facet; break;
17284
0
      case XML_SCHEMA_FACET_FRACTIONDIGITS:
17285
0
    bffracdig = facet; break;
17286
0
      default:
17287
0
    break;
17288
0
  }
17289
0
    }
17290
    /*
17291
    * length and minLength or maxLength (2.2) + (3.2)
17292
    */
17293
0
    if (flength && (fminlen || fmaxlen)) {
17294
0
  FACET_RESTR_ERR(flength, "It is an error for both 'length' and "
17295
0
      "either of 'minLength' or 'maxLength' to be specified on "
17296
0
      "the same type definition")
17297
0
    }
17298
    /*
17299
    * Mutual exclusions in the same derivation step.
17300
    */
17301
0
    if ((fmaxinc) && (fmaxexc)) {
17302
  /*
17303
  * SCC "maxInclusive and maxExclusive"
17304
  */
17305
0
  FACET_RESTR_MUTUAL_ERR(fmaxinc, fmaxexc)
17306
0
    }
17307
0
    if ((fmininc) && (fminexc)) {
17308
  /*
17309
  * SCC "minInclusive and minExclusive"
17310
  */
17311
0
  FACET_RESTR_MUTUAL_ERR(fmininc, fminexc)
17312
0
    }
17313
17314
0
    if (flength && bflength) {
17315
  /*
17316
  * SCC "length valid restriction"
17317
  * The values have to be equal.
17318
  */
17319
0
  res = xmlSchemaCompareValues(flength->val, bflength->val);
17320
0
  if (res == -2)
17321
0
      goto internal_error;
17322
0
  if (res != 0)
17323
0
      xmlSchemaDeriveFacetErr(pctxt, flength, bflength, 0, 0, 1);
17324
0
  if ((res != 0) && (bflength->fixed)) {
17325
0
      FACET_RESTR_FIXED_ERR(flength)
17326
0
  }
17327
17328
0
    }
17329
0
    if (fminlen && bfminlen) {
17330
  /*
17331
  * SCC "minLength valid restriction"
17332
  * minLength >= BASE minLength
17333
  */
17334
0
  res = xmlSchemaCompareValues(fminlen->val, bfminlen->val);
17335
0
  if (res == -2)
17336
0
      goto internal_error;
17337
0
  if (res == -1)
17338
0
      xmlSchemaDeriveFacetErr(pctxt, fminlen, bfminlen, 1, 1, 1);
17339
0
  if ((res != 0) && (bfminlen->fixed)) {
17340
0
      FACET_RESTR_FIXED_ERR(fminlen)
17341
0
  }
17342
0
    }
17343
0
    if (fmaxlen && bfmaxlen) {
17344
  /*
17345
  * SCC "maxLength valid restriction"
17346
  * maxLength <= BASE minLength
17347
  */
17348
0
  res = xmlSchemaCompareValues(fmaxlen->val, bfmaxlen->val);
17349
0
  if (res == -2)
17350
0
      goto internal_error;
17351
0
  if (res == 1)
17352
0
      xmlSchemaDeriveFacetErr(pctxt, fmaxlen, bfmaxlen, -1, 1, 1);
17353
0
  if ((res != 0) && (bfmaxlen->fixed)) {
17354
0
      FACET_RESTR_FIXED_ERR(fmaxlen)
17355
0
  }
17356
0
    }
17357
    /*
17358
    * SCC "length and minLength or maxLength"
17359
    */
17360
0
    if (! flength)
17361
0
  flength = bflength;
17362
0
    if (flength) {
17363
0
  if (! fminlen)
17364
0
      fminlen = bfminlen;
17365
0
  if (fminlen) {
17366
      /* (1.1) length >= minLength */
17367
0
      res = xmlSchemaCompareValues(flength->val, fminlen->val);
17368
0
      if (res == -2)
17369
0
    goto internal_error;
17370
0
      if (res == -1)
17371
0
    xmlSchemaDeriveFacetErr(pctxt, flength, fminlen, 1, 1, 0);
17372
0
  }
17373
0
  if (! fmaxlen)
17374
0
      fmaxlen = bfmaxlen;
17375
0
  if (fmaxlen) {
17376
      /* (2.1) length <= maxLength */
17377
0
      res = xmlSchemaCompareValues(flength->val, fmaxlen->val);
17378
0
      if (res == -2)
17379
0
    goto internal_error;
17380
0
      if (res == 1)
17381
0
    xmlSchemaDeriveFacetErr(pctxt, flength, fmaxlen, -1, 1, 0);
17382
0
  }
17383
0
    }
17384
0
    if (fmaxinc) {
17385
  /*
17386
  * "maxInclusive"
17387
  */
17388
0
  if (fmininc) {
17389
      /* SCC "maxInclusive >= minInclusive" */
17390
0
      res = xmlSchemaCompareValues(fmaxinc->val, fmininc->val);
17391
0
      if (res == -2)
17392
0
    goto internal_error;
17393
0
      if (res == -1) {
17394
0
    xmlSchemaDeriveFacetErr(pctxt, fmaxinc, fmininc, 1, 1, 0);
17395
0
      }
17396
0
  }
17397
  /*
17398
  * SCC "maxInclusive valid restriction"
17399
  */
17400
0
  if (bfmaxinc) {
17401
      /* maxInclusive <= BASE maxInclusive */
17402
0
      res = xmlSchemaCompareValues(fmaxinc->val, bfmaxinc->val);
17403
0
      if (res == -2)
17404
0
    goto internal_error;
17405
0
      if (res == 1)
17406
0
    xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmaxinc, -1, 1, 1);
17407
0
      if ((res != 0) && (bfmaxinc->fixed)) {
17408
0
    FACET_RESTR_FIXED_ERR(fmaxinc)
17409
0
      }
17410
0
  }
17411
0
  if (bfmaxexc) {
17412
      /* maxInclusive < BASE maxExclusive */
17413
0
      res = xmlSchemaCompareValues(fmaxinc->val, bfmaxexc->val);
17414
0
      if (res == -2)
17415
0
    goto internal_error;
17416
0
      if (res != -1) {
17417
0
    xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmaxexc, -1, 0, 1);
17418
0
      }
17419
0
  }
17420
0
  if (bfmininc) {
17421
      /* maxInclusive >= BASE minInclusive */
17422
0
      res = xmlSchemaCompareValues(fmaxinc->val, bfmininc->val);
17423
0
      if (res == -2)
17424
0
    goto internal_error;
17425
0
      if (res == -1) {
17426
0
    xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmininc, 1, 1, 1);
17427
0
      }
17428
0
  }
17429
0
  if (bfminexc) {
17430
      /* maxInclusive > BASE minExclusive */
17431
0
      res = xmlSchemaCompareValues(fmaxinc->val, bfminexc->val);
17432
0
      if (res == -2)
17433
0
    goto internal_error;
17434
0
      if (res != 1) {
17435
0
    xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfminexc, 1, 0, 1);
17436
0
      }
17437
0
  }
17438
0
    }
17439
0
    if (fmaxexc) {
17440
  /*
17441
  * "maxExclusive >= minExclusive"
17442
  */
17443
0
  if (fminexc) {
17444
0
      res = xmlSchemaCompareValues(fmaxexc->val, fminexc->val);
17445
0
      if (res == -2)
17446
0
    goto internal_error;
17447
0
      if (res == -1) {
17448
0
    xmlSchemaDeriveFacetErr(pctxt, fmaxexc, fminexc, 1, 1, 0);
17449
0
      }
17450
0
  }
17451
  /*
17452
  * "maxExclusive valid restriction"
17453
  */
17454
0
  if (bfmaxexc) {
17455
      /* maxExclusive <= BASE maxExclusive */
17456
0
      res = xmlSchemaCompareValues(fmaxexc->val, bfmaxexc->val);
17457
0
      if (res == -2)
17458
0
    goto internal_error;
17459
0
      if (res == 1) {
17460
0
    xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmaxexc, -1, 1, 1);
17461
0
      }
17462
0
      if ((res != 0) && (bfmaxexc->fixed)) {
17463
0
    FACET_RESTR_FIXED_ERR(fmaxexc)
17464
0
      }
17465
0
  }
17466
0
  if (bfmaxinc) {
17467
      /* maxExclusive <= BASE maxInclusive */
17468
0
      res = xmlSchemaCompareValues(fmaxexc->val, bfmaxinc->val);
17469
0
      if (res == -2)
17470
0
    goto internal_error;
17471
0
      if (res == 1) {
17472
0
    xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmaxinc, -1, 1, 1);
17473
0
      }
17474
0
  }
17475
0
  if (bfmininc) {
17476
      /* maxExclusive > BASE minInclusive */
17477
0
      res = xmlSchemaCompareValues(fmaxexc->val, bfmininc->val);
17478
0
      if (res == -2)
17479
0
    goto internal_error;
17480
0
      if (res != 1) {
17481
0
    xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmininc, 1, 0, 1);
17482
0
      }
17483
0
  }
17484
0
  if (bfminexc) {
17485
      /* maxExclusive > BASE minExclusive */
17486
0
      res = xmlSchemaCompareValues(fmaxexc->val, bfminexc->val);
17487
0
      if (res == -2)
17488
0
    goto internal_error;
17489
0
      if (res != 1) {
17490
0
    xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfminexc, 1, 0, 1);
17491
0
      }
17492
0
  }
17493
0
    }
17494
0
    if (fminexc) {
17495
  /*
17496
  * "minExclusive < maxInclusive"
17497
  */
17498
0
  if (fmaxinc) {
17499
0
      res = xmlSchemaCompareValues(fminexc->val, fmaxinc->val);
17500
0
      if (res == -2)
17501
0
    goto internal_error;
17502
0
      if (res != -1) {
17503
0
    xmlSchemaDeriveFacetErr(pctxt, fminexc, fmaxinc, -1, 0, 0);
17504
0
      }
17505
0
  }
17506
  /*
17507
  * "minExclusive valid restriction"
17508
  */
17509
0
  if (bfminexc) {
17510
      /* minExclusive >= BASE minExclusive */
17511
0
      res = xmlSchemaCompareValues(fminexc->val, bfminexc->val);
17512
0
      if (res == -2)
17513
0
    goto internal_error;
17514
0
      if (res == -1) {
17515
0
    xmlSchemaDeriveFacetErr(pctxt, fminexc, bfminexc, 1, 1, 1);
17516
0
      }
17517
0
      if ((res != 0) && (bfminexc->fixed)) {
17518
0
    FACET_RESTR_FIXED_ERR(fminexc)
17519
0
      }
17520
0
  }
17521
0
  if (bfmaxinc) {
17522
      /* minExclusive <= BASE maxInclusive */
17523
0
      res = xmlSchemaCompareValues(fminexc->val, bfmaxinc->val);
17524
0
      if (res == -2)
17525
0
    goto internal_error;
17526
0
      if (res == 1) {
17527
0
    xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmaxinc, -1, 1, 1);
17528
0
      }
17529
0
  }
17530
0
  if (bfmininc) {
17531
      /* minExclusive >= BASE minInclusive */
17532
0
      res = xmlSchemaCompareValues(fminexc->val, bfmininc->val);
17533
0
      if (res == -2)
17534
0
    goto internal_error;
17535
0
      if (res == -1) {
17536
0
    xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmininc, 1, 1, 1);
17537
0
      }
17538
0
  }
17539
0
  if (bfmaxexc) {
17540
      /* minExclusive < BASE maxExclusive */
17541
0
      res = xmlSchemaCompareValues(fminexc->val, bfmaxexc->val);
17542
0
      if (res == -2)
17543
0
    goto internal_error;
17544
0
      if (res != -1) {
17545
0
    xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmaxexc, -1, 0, 1);
17546
0
      }
17547
0
  }
17548
0
    }
17549
0
    if (fmininc) {
17550
  /*
17551
  * "minInclusive < maxExclusive"
17552
  */
17553
0
  if (fmaxexc) {
17554
0
      res = xmlSchemaCompareValues(fmininc->val, fmaxexc->val);
17555
0
      if (res == -2)
17556
0
    goto internal_error;
17557
0
      if (res != -1) {
17558
0
    xmlSchemaDeriveFacetErr(pctxt, fmininc, fmaxexc, -1, 0, 0);
17559
0
      }
17560
0
  }
17561
  /*
17562
  * "minExclusive valid restriction"
17563
  */
17564
0
  if (bfmininc) {
17565
      /* minInclusive >= BASE minInclusive */
17566
0
      res = xmlSchemaCompareValues(fmininc->val, bfmininc->val);
17567
0
      if (res == -2)
17568
0
    goto internal_error;
17569
0
      if (res == -1) {
17570
0
    xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmininc, 1, 1, 1);
17571
0
      }
17572
0
      if ((res != 0) && (bfmininc->fixed)) {
17573
0
    FACET_RESTR_FIXED_ERR(fmininc)
17574
0
      }
17575
0
  }
17576
0
  if (bfmaxinc) {
17577
      /* minInclusive <= BASE maxInclusive */
17578
0
      res = xmlSchemaCompareValues(fmininc->val, bfmaxinc->val);
17579
0
      if (res == -2)
17580
0
    goto internal_error;
17581
0
      if (res == 1) {
17582
0
    xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmaxinc, -1, 1, 1);
17583
0
      }
17584
0
  }
17585
0
  if (bfminexc) {
17586
      /* minInclusive > BASE minExclusive */
17587
0
      res = xmlSchemaCompareValues(fmininc->val, bfminexc->val);
17588
0
      if (res == -2)
17589
0
    goto internal_error;
17590
0
      if (res != 1)
17591
0
    xmlSchemaDeriveFacetErr(pctxt, fmininc, bfminexc, 1, 0, 1);
17592
0
  }
17593
0
  if (bfmaxexc) {
17594
      /* minInclusive < BASE maxExclusive */
17595
0
      res = xmlSchemaCompareValues(fmininc->val, bfmaxexc->val);
17596
0
      if (res == -2)
17597
0
    goto internal_error;
17598
0
      if (res != -1)
17599
0
    xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmaxexc, -1, 0, 1);
17600
0
  }
17601
0
    }
17602
0
    if (ftotdig && bftotdig) {
17603
  /*
17604
  * SCC " totalDigits valid restriction"
17605
  * totalDigits <= BASE totalDigits
17606
  */
17607
0
  res = xmlSchemaCompareValues(ftotdig->val, bftotdig->val);
17608
0
  if (res == -2)
17609
0
      goto internal_error;
17610
0
  if (res == 1)
17611
0
      xmlSchemaDeriveFacetErr(pctxt, ftotdig, bftotdig,
17612
0
      -1, 1, 1);
17613
0
  if ((res != 0) && (bftotdig->fixed)) {
17614
0
      FACET_RESTR_FIXED_ERR(ftotdig)
17615
0
  }
17616
0
    }
17617
0
    if (ffracdig && bffracdig) {
17618
  /*
17619
  * SCC  "fractionDigits valid restriction"
17620
  * fractionDigits <= BASE fractionDigits
17621
  */
17622
0
  res = xmlSchemaCompareValues(ffracdig->val, bffracdig->val);
17623
0
  if (res == -2)
17624
0
      goto internal_error;
17625
0
  if (res == 1)
17626
0
      xmlSchemaDeriveFacetErr(pctxt, ffracdig, bffracdig,
17627
0
      -1, 1, 1);
17628
0
  if ((res != 0) && (bffracdig->fixed)) {
17629
0
      FACET_RESTR_FIXED_ERR(ffracdig)
17630
0
  }
17631
0
    }
17632
    /*
17633
    * SCC "fractionDigits less than or equal to totalDigits"
17634
    */
17635
0
    if (! ftotdig)
17636
0
  ftotdig = bftotdig;
17637
0
    if (! ffracdig)
17638
0
  ffracdig = bffracdig;
17639
0
    if (ftotdig && ffracdig) {
17640
0
  res = xmlSchemaCompareValues(ffracdig->val, ftotdig->val);
17641
0
  if (res == -2)
17642
0
      goto internal_error;
17643
0
  if (res == 1)
17644
0
      xmlSchemaDeriveFacetErr(pctxt, ffracdig, ftotdig,
17645
0
    -1, 1, 0);
17646
0
    }
17647
    /*
17648
    * *Enumerations* won' be added here, since only the first set
17649
    * of enumerations in the ancestor-or-self axis is used
17650
    * for validation, plus we need to use the base type of those
17651
    * enumerations for whitespace.
17652
    *
17653
    * *Patterns*: won't be add here, since they are ORed at
17654
    * type level and ANDed at ancestor level. This will
17655
    * happen during validation by walking the base axis
17656
    * of the type.
17657
    */
17658
0
    for (cur = base->facetSet; cur != NULL; cur = cur->next) {
17659
0
  bfacet = cur->facet;
17660
  /*
17661
  * Special handling of enumerations and patterns.
17662
  * TODO: hmm, they should not appear in the set, so remove this.
17663
  */
17664
0
  if ((bfacet->type == XML_SCHEMA_FACET_PATTERN) ||
17665
0
      (bfacet->type == XML_SCHEMA_FACET_ENUMERATION))
17666
0
      continue;
17667
  /*
17668
  * Search for a duplicate facet in the current type.
17669
  */
17670
0
  link = type->facetSet;
17671
  /* err = 0; */
17672
  /* fixedErr = 0; */
17673
0
  while (link != NULL) {
17674
0
      facet = link->facet;
17675
0
      if (facet->type == bfacet->type) {
17676
0
    switch (facet->type) {
17677
0
        case XML_SCHEMA_FACET_WHITESPACE:
17678
      /*
17679
      * The whitespace must be stronger.
17680
      */
17681
0
      if (facet->whitespace < bfacet->whitespace) {
17682
0
          FACET_RESTR_ERR(facet,
17683
0
        "The 'whitespace' value has to be equal to "
17684
0
        "or stronger than the 'whitespace' value of "
17685
0
        "the base type")
17686
0
      }
17687
0
      if ((bfacet->fixed) &&
17688
0
          (facet->whitespace != bfacet->whitespace)) {
17689
0
          FACET_RESTR_FIXED_ERR(facet)
17690
0
      }
17691
0
      break;
17692
0
        default:
17693
0
      break;
17694
0
    }
17695
    /* Duplicate found. */
17696
0
    break;
17697
0
      }
17698
0
      link = link->next;
17699
0
  }
17700
  /*
17701
  * If no duplicate was found: add the base types's facet
17702
  * to the set.
17703
  */
17704
0
  if (link == NULL) {
17705
0
      link = (xmlSchemaFacetLinkPtr)
17706
0
    xmlMalloc(sizeof(xmlSchemaFacetLink));
17707
0
      if (link == NULL) {
17708
0
    xmlSchemaPErrMemory(pctxt);
17709
0
    return (-1);
17710
0
      }
17711
0
      link->facet = cur->facet;
17712
0
      link->next = NULL;
17713
0
      if (last == NULL)
17714
0
    type->facetSet = link;
17715
0
      else
17716
0
    last->next = link;
17717
0
      last = link;
17718
0
  }
17719
17720
0
    }
17721
17722
0
    return (0);
17723
0
internal_error:
17724
0
    PERROR_INT("xmlSchemaDeriveAndValidateFacets",
17725
0
  "an error occurred");
17726
0
    return (-1);
17727
0
}
17728
17729
static int
17730
xmlSchemaFinishMemberTypeDefinitionsProperty(xmlSchemaParserCtxtPtr pctxt,
17731
               xmlSchemaTypePtr type)
17732
0
{
17733
0
    xmlSchemaTypeLinkPtr link, lastLink, prevLink, subLink, newLink;
17734
    /*
17735
    * The actual value is then formed by replacing any union type
17736
    * definition in the `explicit members` with the members of their
17737
    * {member type definitions}, in order.
17738
    *
17739
    * TODO: There's a bug entry at
17740
    * "http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0287.html"
17741
    * which indicates that we'll keep the union types the future.
17742
    */
17743
0
    link = type->memberTypes;
17744
0
    while (link != NULL) {
17745
17746
0
  if (WXS_IS_TYPE_NOT_FIXED(link->type))
17747
0
      xmlSchemaTypeFixup(link->type, ACTXT_CAST pctxt);
17748
17749
0
  if (WXS_IS_UNION(link->type)) {
17750
0
      subLink = xmlSchemaGetUnionSimpleTypeMemberTypes(link->type);
17751
0
      if (subLink != NULL) {
17752
0
    link->type = subLink->type;
17753
0
    if (subLink->next != NULL) {
17754
0
        lastLink = link->next;
17755
0
        subLink = subLink->next;
17756
0
        prevLink = link;
17757
0
        while (subLink != NULL) {
17758
0
      newLink = (xmlSchemaTypeLinkPtr)
17759
0
          xmlMalloc(sizeof(xmlSchemaTypeLink));
17760
0
      if (newLink == NULL) {
17761
0
          xmlSchemaPErrMemory(pctxt);
17762
0
          return (-1);
17763
0
      }
17764
0
      newLink->type = subLink->type;
17765
0
      prevLink->next = newLink;
17766
0
      prevLink = newLink;
17767
0
      newLink->next = lastLink;
17768
17769
0
      subLink = subLink->next;
17770
0
        }
17771
0
    }
17772
0
      }
17773
0
  }
17774
0
  link = link->next;
17775
0
    }
17776
0
    return (0);
17777
0
}
17778
17779
static void
17780
xmlSchemaTypeFixupOptimFacets(xmlSchemaTypePtr type)
17781
0
{
17782
0
    int has = 0, needVal = 0, normVal = 0;
17783
17784
0
    has = (type->baseType->flags & XML_SCHEMAS_TYPE_HAS_FACETS) ? 1 : 0;
17785
0
    if (has) {
17786
0
  needVal = (type->baseType->flags &
17787
0
      XML_SCHEMAS_TYPE_FACETSNEEDVALUE) ? 1 : 0;
17788
0
  normVal = (type->baseType->flags &
17789
0
      XML_SCHEMAS_TYPE_NORMVALUENEEDED) ? 1 : 0;
17790
0
    }
17791
0
    if (type->facets != NULL) {
17792
0
  xmlSchemaFacetPtr fac;
17793
17794
0
  for (fac = type->facets; fac != NULL; fac = fac->next) {
17795
0
      switch (fac->type) {
17796
0
    case XML_SCHEMA_FACET_WHITESPACE:
17797
0
        break;
17798
0
    case XML_SCHEMA_FACET_PATTERN:
17799
0
        normVal = 1;
17800
0
        has = 1;
17801
0
        break;
17802
0
    case XML_SCHEMA_FACET_ENUMERATION:
17803
0
        needVal = 1;
17804
0
        normVal = 1;
17805
0
        has = 1;
17806
0
        break;
17807
0
    default:
17808
0
        has = 1;
17809
0
        break;
17810
0
      }
17811
0
  }
17812
0
    }
17813
0
    if (normVal)
17814
0
  type->flags |= XML_SCHEMAS_TYPE_NORMVALUENEEDED;
17815
0
    if (needVal)
17816
0
  type->flags |= XML_SCHEMAS_TYPE_FACETSNEEDVALUE;
17817
0
    if (has)
17818
0
  type->flags |= XML_SCHEMAS_TYPE_HAS_FACETS;
17819
17820
0
    if (has && (! needVal) && WXS_IS_ATOMIC(type)) {
17821
0
  xmlSchemaTypePtr prim = xmlSchemaGetPrimitiveType(type);
17822
  /*
17823
  * OPTIMIZE VAL TODO: Some facets need a computed value.
17824
  */
17825
0
  if ((prim->builtInType != XML_SCHEMAS_ANYSIMPLETYPE) &&
17826
0
      (prim->builtInType != XML_SCHEMAS_STRING)) {
17827
0
      type->flags |= XML_SCHEMAS_TYPE_FACETSNEEDVALUE;
17828
0
  }
17829
0
    }
17830
0
}
17831
17832
static int
17833
xmlSchemaTypeFixupWhitespace(xmlSchemaTypePtr type)
17834
0
{
17835
17836
17837
    /*
17838
    * Evaluate the whitespace-facet value.
17839
    */
17840
0
    if (WXS_IS_LIST(type)) {
17841
0
  type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE;
17842
0
  return (0);
17843
0
    } else if (WXS_IS_UNION(type))
17844
0
  return (0);
17845
17846
0
    if (type->facetSet != NULL) {
17847
0
  xmlSchemaFacetLinkPtr lin;
17848
17849
0
  for (lin = type->facetSet; lin != NULL; lin = lin->next) {
17850
0
      if (lin->facet->type == XML_SCHEMA_FACET_WHITESPACE) {
17851
0
    switch (lin->facet->whitespace) {
17852
0
    case XML_SCHEMAS_FACET_PRESERVE:
17853
0
        type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE;
17854
0
        break;
17855
0
    case XML_SCHEMAS_FACET_REPLACE:
17856
0
        type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_REPLACE;
17857
0
        break;
17858
0
    case XML_SCHEMAS_FACET_COLLAPSE:
17859
0
        type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE;
17860
0
        break;
17861
0
    default:
17862
0
        return (-1);
17863
0
    }
17864
0
    return (0);
17865
0
      }
17866
0
  }
17867
0
    }
17868
    /*
17869
    * For all `atomic` datatypes other than string (and types `derived`
17870
    * by `restriction` from it) the value of whiteSpace is fixed to
17871
    * collapse
17872
    */
17873
0
    {
17874
0
  xmlSchemaTypePtr anc;
17875
17876
0
  for (anc = type->baseType; anc != NULL &&
17877
0
    anc->builtInType != XML_SCHEMAS_ANYTYPE;
17878
0
    anc = anc->baseType) {
17879
17880
0
      if (anc->type == XML_SCHEMA_TYPE_BASIC) {
17881
0
    if (anc->builtInType == XML_SCHEMAS_NORMSTRING) {
17882
0
        type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_REPLACE;
17883
17884
0
    } else if ((anc->builtInType == XML_SCHEMAS_STRING) ||
17885
0
        (anc->builtInType == XML_SCHEMAS_ANYSIMPLETYPE)) {
17886
0
        type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE;
17887
17888
0
    } else
17889
0
        type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE;
17890
0
    break;
17891
0
      }
17892
0
  }
17893
0
    }
17894
0
    return (0);
17895
0
}
17896
17897
static int
17898
xmlSchemaFixupSimpleTypeStageOne(xmlSchemaParserCtxtPtr pctxt,
17899
        xmlSchemaTypePtr type)
17900
0
{
17901
0
    if (type->type != XML_SCHEMA_TYPE_SIMPLE)
17902
0
  return(0);
17903
0
    if (! WXS_IS_TYPE_NOT_FIXED_1(type))
17904
0
  return(0);
17905
0
    type->flags |= XML_SCHEMAS_TYPE_FIXUP_1;
17906
17907
0
    if (WXS_IS_LIST(type)) {
17908
  /*
17909
  * Corresponds to <simpleType><list>...
17910
  */
17911
0
  if (type->subtypes == NULL) {
17912
      /*
17913
      * This one is really needed, so get out.
17914
      */
17915
0
      PERROR_INT("xmlSchemaFixupSimpleTypeStageOne",
17916
0
    "list type has no item-type assigned");
17917
0
      return(-1);
17918
0
  }
17919
0
    } else if (WXS_IS_UNION(type)) {
17920
  /*
17921
  * Corresponds to <simpleType><union>...
17922
  */
17923
0
  if (type->memberTypes == NULL) {
17924
      /*
17925
      * This one is really needed, so get out.
17926
      */
17927
0
      PERROR_INT("xmlSchemaFixupSimpleTypeStageOne",
17928
0
    "union type has no member-types assigned");
17929
0
      return(-1);
17930
0
  }
17931
0
    } else {
17932
  /*
17933
  * Corresponds to <simpleType><restriction>...
17934
  */
17935
0
  if (type->baseType == NULL) {
17936
0
      PERROR_INT("xmlSchemaFixupSimpleTypeStageOne",
17937
0
    "type has no base-type assigned");
17938
0
      return(-1);
17939
0
  }
17940
0
  if (WXS_IS_TYPE_NOT_FIXED_1(type->baseType))
17941
0
      if (xmlSchemaFixupSimpleTypeStageOne(pctxt, type->baseType) == -1)
17942
0
    return(-1);
17943
  /*
17944
  * Variety
17945
  * If the <restriction> alternative is chosen, then the
17946
  * {variety} of the {base type definition}.
17947
  */
17948
0
  if (WXS_IS_ATOMIC(type->baseType))
17949
0
      type->flags |= XML_SCHEMAS_TYPE_VARIETY_ATOMIC;
17950
0
  else if (WXS_IS_LIST(type->baseType)) {
17951
0
      type->flags |= XML_SCHEMAS_TYPE_VARIETY_LIST;
17952
      /*
17953
      * Inherit the itemType.
17954
      */
17955
0
      type->subtypes = type->baseType->subtypes;
17956
0
  } else if (WXS_IS_UNION(type->baseType)) {
17957
0
      type->flags |= XML_SCHEMAS_TYPE_VARIETY_UNION;
17958
      /*
17959
      * NOTE that we won't assign the memberTypes of the base,
17960
      * since this will make trouble when freeing them; we will
17961
      * use a lookup function to access them instead.
17962
      */
17963
0
  }
17964
0
    }
17965
0
    return(0);
17966
0
}
17967
17968
/*
17969
* 3.14.6 Constraints on Simple Type Definition Schema Components
17970
*/
17971
static int
17972
xmlSchemaFixupSimpleTypeStageTwo(xmlSchemaParserCtxtPtr pctxt,
17973
         xmlSchemaTypePtr type)
17974
0
{
17975
0
    int res, olderrs = pctxt->nberrors;
17976
17977
0
    if (type->type != XML_SCHEMA_TYPE_SIMPLE)
17978
0
  return(-1);
17979
17980
0
    if (! WXS_IS_TYPE_NOT_FIXED(type))
17981
0
  return(0);
17982
17983
0
    type->flags |= XML_SCHEMAS_TYPE_INTERNAL_RESOLVED;
17984
0
    type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
17985
17986
0
    if (type->baseType == NULL) {
17987
0
  PERROR_INT("xmlSchemaFixupSimpleTypeStageTwo",
17988
0
      "missing baseType");
17989
0
  goto exit_failure;
17990
0
    }
17991
0
    if (WXS_IS_TYPE_NOT_FIXED(type->baseType))
17992
0
  xmlSchemaTypeFixup(type->baseType, ACTXT_CAST pctxt);
17993
    /*
17994
    * If a member type of a union is a union itself, we need to substitute
17995
    * that member type for its member types.
17996
    * NOTE that this might change in WXS 1.1; i.e. we will keep the union
17997
    * types in WXS 1.1.
17998
    */
17999
0
    if ((type->memberTypes != NULL) &&
18000
0
  (xmlSchemaFinishMemberTypeDefinitionsProperty(pctxt, type) == -1))
18001
0
  return(-1);
18002
    /*
18003
    * SPEC src-simple-type 1
18004
    * "The corresponding simple type definition, if any, must satisfy
18005
    * the conditions set out in Constraints on Simple Type Definition
18006
    * Schema Components ($3.14.6)."
18007
    */
18008
    /*
18009
    * Schema Component Constraint: Simple Type Definition Properties Correct
18010
    * (st-props-correct)
18011
    */
18012
0
    res = xmlSchemaCheckSTPropsCorrect(pctxt, type);
18013
0
    HFAILURE HERROR
18014
    /*
18015
    * Schema Component Constraint: Derivation Valid (Restriction, Simple)
18016
    * (cos-st-restricts)
18017
    */
18018
0
    res = xmlSchemaCheckCOSSTRestricts(pctxt, type);
18019
0
    HFAILURE HERROR
18020
    /*
18021
    * TODO: Removed the error report, since it got annoying to get an
18022
    * extra error report, if anything failed until now.
18023
    * Enable this if needed.
18024
    *
18025
    * xmlSchemaPErr(ctxt, type->node,
18026
    *    XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
18027
    *    "Simple type '%s' does not satisfy the constraints "
18028
    *    "on simple type definitions.\n",
18029
    *    type->name, NULL);
18030
    */
18031
    /*
18032
    * Schema Component Constraint: Simple Type Restriction (Facets)
18033
    * (st-restrict-facets)
18034
    */
18035
0
    res = xmlSchemaCheckFacetValues(type, pctxt);
18036
0
    HFAILURE HERROR
18037
0
    if ((type->facetSet != NULL) ||
18038
0
  (type->baseType->facetSet != NULL)) {
18039
0
  res = xmlSchemaDeriveAndValidateFacets(pctxt, type);
18040
0
  HFAILURE HERROR
18041
0
    }
18042
    /*
18043
    * Whitespace value.
18044
    */
18045
0
    res = xmlSchemaTypeFixupWhitespace(type);
18046
0
    HFAILURE HERROR
18047
0
    xmlSchemaTypeFixupOptimFacets(type);
18048
18049
0
exit_error:
18050
0
    if (olderrs != pctxt->nberrors)
18051
0
  return(pctxt->err);
18052
0
    return(0);
18053
18054
0
exit_failure:
18055
0
    return(-1);
18056
0
}
18057
18058
static int
18059
xmlSchemaFixupComplexType(xmlSchemaParserCtxtPtr pctxt,
18060
        xmlSchemaTypePtr type)
18061
0
{
18062
0
    int res = 0, olderrs = pctxt->nberrors;
18063
0
    xmlSchemaTypePtr baseType = type->baseType;
18064
18065
0
    if (! WXS_IS_TYPE_NOT_FIXED(type))
18066
0
  return(0);
18067
0
    type->flags |= XML_SCHEMAS_TYPE_INTERNAL_RESOLVED;
18068
0
    if (baseType == NULL) {
18069
0
  PERROR_INT("xmlSchemaFixupComplexType",
18070
0
      "missing baseType");
18071
0
  goto exit_failure;
18072
0
    }
18073
    /*
18074
    * Fixup the base type.
18075
    */
18076
0
    if (WXS_IS_TYPE_NOT_FIXED(baseType))
18077
0
  xmlSchemaTypeFixup(baseType, ACTXT_CAST pctxt);
18078
0
    if (baseType->flags & XML_SCHEMAS_TYPE_INTERNAL_INVALID) {
18079
  /*
18080
  * Skip fixup if the base type is invalid.
18081
  * TODO: Generate a warning!
18082
  */
18083
0
  return(0);
18084
0
    }
18085
    /*
18086
    * This basically checks if the base type can be derived.
18087
    */
18088
0
    res = xmlSchemaCheckSRCCT(pctxt, type);
18089
0
    HFAILURE HERROR
18090
    /*
18091
    * Fixup the content type.
18092
    */
18093
0
    if (type->contentType == XML_SCHEMA_CONTENT_SIMPLE) {
18094
  /*
18095
  * Corresponds to <complexType><simpleContent>...
18096
  */
18097
0
  if ((WXS_IS_COMPLEX(baseType)) &&
18098
0
      (baseType->contentTypeDef != NULL) &&
18099
0
      (WXS_IS_RESTRICTION(type))) {
18100
0
      xmlSchemaTypePtr contentBase, content;
18101
#ifdef ENABLE_NAMED_LOCALS
18102
      char buf[30];
18103
      const xmlChar *tmpname;
18104
#endif
18105
      /*
18106
      * SPEC (1) If <restriction> + base type is <complexType>,
18107
      * "whose own {content type} is a simple type..."
18108
      */
18109
0
      if (type->contentTypeDef != NULL) {
18110
    /*
18111
    * SPEC (1.1) "the simple type definition corresponding to the
18112
    * <simpleType> among the [children] of <restriction> if there
18113
    * is one;"
18114
    * Note that this "<simpleType> among the [children]" was put
18115
    * into ->contentTypeDef during parsing.
18116
    */
18117
0
    contentBase = type->contentTypeDef;
18118
0
    type->contentTypeDef = NULL;
18119
0
      } else {
18120
    /*
18121
    * (1.2) "...otherwise (<restriction> has no <simpleType>
18122
    * among its [children]), the simple type definition which
18123
    * is the {content type} of the ... base type."
18124
    */
18125
0
    contentBase = baseType->contentTypeDef;
18126
0
      }
18127
      /*
18128
      * SPEC
18129
      * "... a simple type definition which restricts the simple
18130
      * type definition identified in clause 1.1 or clause 1.2
18131
      * with a set of facet components"
18132
      *
18133
      * Create the anonymous simple type, which will be the content
18134
      * type of the complex type.
18135
      */
18136
#ifdef ENABLE_NAMED_LOCALS
18137
      snprintf(buf, 29, "#scST%d", ++(pctxt->counter));
18138
      tmpname = xmlDictLookup(pctxt->dict, BAD_CAST buf, -1);
18139
      content = xmlSchemaAddType(pctxt, pctxt->schema,
18140
    XML_SCHEMA_TYPE_SIMPLE, tmpname, type->targetNamespace,
18141
    type->node, 0);
18142
#else
18143
0
      content = xmlSchemaAddType(pctxt, pctxt->schema,
18144
0
    XML_SCHEMA_TYPE_SIMPLE, NULL, type->targetNamespace,
18145
0
    type->node, 0);
18146
0
#endif
18147
0
      if (content == NULL)
18148
0
    goto exit_failure;
18149
      /*
18150
      * We will use the same node as for the <complexType>
18151
      * to have it somehow anchored in the schema doc.
18152
      */
18153
0
      content->type = XML_SCHEMA_TYPE_SIMPLE;
18154
0
      content->baseType = contentBase;
18155
      /*
18156
      * Move the facets, previously anchored on the
18157
      * complexType during parsing.
18158
      */
18159
0
      content->facets = type->facets;
18160
0
      type->facets = NULL;
18161
0
      content->facetSet = type->facetSet;
18162
0
      type->facetSet = NULL;
18163
18164
0
      type->contentTypeDef = content;
18165
0
      if (WXS_IS_TYPE_NOT_FIXED(contentBase))
18166
0
    xmlSchemaTypeFixup(contentBase, ACTXT_CAST pctxt);
18167
      /*
18168
      * Fixup the newly created type. We don't need to check
18169
      * for circularity here.
18170
      */
18171
0
      res = xmlSchemaFixupSimpleTypeStageOne(pctxt, content);
18172
0
      HFAILURE HERROR
18173
0
      res = xmlSchemaFixupSimpleTypeStageTwo(pctxt, content);
18174
0
      HFAILURE HERROR
18175
18176
0
  } else if ((WXS_IS_COMPLEX(baseType)) &&
18177
0
      (baseType->contentType == XML_SCHEMA_CONTENT_MIXED) &&
18178
0
      (WXS_IS_RESTRICTION(type))) {
18179
      /*
18180
      * SPEC (2) If <restriction> + base is a mixed <complexType> with
18181
      * an emptiable particle, then a simple type definition which
18182
      * restricts the <restriction>'s <simpleType> child.
18183
      */
18184
0
      if ((type->contentTypeDef == NULL) ||
18185
0
    (type->contentTypeDef->baseType == NULL)) {
18186
    /*
18187
    * TODO: Check if this ever happens.
18188
    */
18189
0
    xmlSchemaPCustomErr(pctxt,
18190
0
        XML_SCHEMAP_INTERNAL,
18191
0
        WXS_BASIC_CAST type, NULL,
18192
0
        "Internal error: xmlSchemaTypeFixup, "
18193
0
        "complex type '%s': the <simpleContent><restriction> "
18194
0
        "is missing a <simpleType> child, but was not caught "
18195
0
        "by xmlSchemaCheckSRCCT()", type->name);
18196
0
    goto exit_failure;
18197
0
      }
18198
0
  } else if ((WXS_IS_COMPLEX(baseType)) && WXS_IS_EXTENSION(type)) {
18199
      /*
18200
      * SPEC (3) If <extension> + base is <complexType> with
18201
      * <simpleType> content, "...then the {content type} of that
18202
      * complex type definition"
18203
      */
18204
0
      if (baseType->contentTypeDef == NULL) {
18205
    /*
18206
    * TODO: Check if this ever happens. xmlSchemaCheckSRCCT
18207
    * should have caught this already.
18208
    */
18209
0
    xmlSchemaPCustomErr(pctxt,
18210
0
        XML_SCHEMAP_INTERNAL,
18211
0
        WXS_BASIC_CAST type, NULL,
18212
0
        "Internal error: xmlSchemaTypeFixup, "
18213
0
        "complex type '%s': the <extension>ed base type is "
18214
0
        "a complex type with no simple content type",
18215
0
        type->name);
18216
0
    goto exit_failure;
18217
0
      }
18218
0
      type->contentTypeDef = baseType->contentTypeDef;
18219
0
  } else if ((WXS_IS_SIMPLE(baseType)) && WXS_IS_EXTENSION(type)) {
18220
      /*
18221
      * SPEC (4) <extension> + base is <simpleType>
18222
      * "... then that simple type definition"
18223
      */
18224
0
      type->contentTypeDef = baseType;
18225
0
  } else {
18226
      /*
18227
      * TODO: Check if this ever happens.
18228
      */
18229
0
      xmlSchemaPCustomErr(pctxt,
18230
0
    XML_SCHEMAP_INTERNAL,
18231
0
    WXS_BASIC_CAST type, NULL,
18232
0
    "Internal error: xmlSchemaTypeFixup, "
18233
0
    "complex type '%s' with <simpleContent>: unhandled "
18234
0
    "derivation case", type->name);
18235
0
      goto exit_failure;
18236
0
  }
18237
0
    } else {
18238
0
  int dummySequence = 0;
18239
0
  xmlSchemaParticlePtr particle =
18240
0
      (xmlSchemaParticlePtr) type->subtypes;
18241
  /*
18242
  * Corresponds to <complexType><complexContent>...
18243
  *
18244
  * NOTE that the effective mixed was already set during parsing of
18245
  * <complexType> and <complexContent>; its flag value is
18246
  * XML_SCHEMAS_TYPE_MIXED.
18247
  *
18248
  * Compute the "effective content":
18249
  * (2.1.1) + (2.1.2) + (2.1.3)
18250
  */
18251
0
  if ((particle == NULL) ||
18252
0
      ((particle->type == XML_SCHEMA_TYPE_PARTICLE) &&
18253
0
      ((particle->children->type == XML_SCHEMA_TYPE_ALL) ||
18254
0
      (particle->children->type == XML_SCHEMA_TYPE_SEQUENCE) ||
18255
0
      ((particle->children->type == XML_SCHEMA_TYPE_CHOICE) &&
18256
0
      (particle->minOccurs == 0))) &&
18257
0
      ( ((xmlSchemaTreeItemPtr) particle->children)->children == NULL))) {
18258
0
      if (type->flags & XML_SCHEMAS_TYPE_MIXED) {
18259
    /*
18260
    * SPEC (2.1.4) "If the `effective mixed` is true, then
18261
    * a particle whose properties are as follows:..."
18262
    *
18263
    * Empty sequence model group with
18264
    * minOccurs/maxOccurs = 1 (i.e. a "particle emptiable").
18265
    * NOTE that we sill assign it the <complexType> node to
18266
    * somehow anchor it in the doc.
18267
    */
18268
0
    if ((particle == NULL) ||
18269
0
        (particle->children->type != XML_SCHEMA_TYPE_SEQUENCE)) {
18270
        /*
18271
        * Create the particle.
18272
        */
18273
0
        particle = xmlSchemaAddParticle(pctxt,
18274
0
      type->node, 1, 1);
18275
0
        if (particle == NULL)
18276
0
      goto exit_failure;
18277
        /*
18278
        * Create the model group.
18279
        */ /* URGENT TODO: avoid adding to pending items. */
18280
0
        particle->children = (xmlSchemaTreeItemPtr)
18281
0
      xmlSchemaAddModelGroup(pctxt, pctxt->schema,
18282
0
      XML_SCHEMA_TYPE_SEQUENCE, type->node);
18283
0
        if (particle->children == NULL)
18284
0
      goto exit_failure;
18285
18286
0
        type->subtypes = (xmlSchemaTypePtr) particle;
18287
0
    }
18288
0
    dummySequence = 1;
18289
0
    type->contentType = XML_SCHEMA_CONTENT_ELEMENTS;
18290
0
      } else {
18291
    /*
18292
    * SPEC (2.1.5) "otherwise empty"
18293
    */
18294
0
    type->contentType = XML_SCHEMA_CONTENT_EMPTY;
18295
0
      }
18296
0
  } else {
18297
      /*
18298
      * SPEC (2.2) "otherwise the particle corresponding to the
18299
      * <all>, <choice>, <group> or <sequence> among the
18300
      * [children]."
18301
      */
18302
0
      type->contentType = XML_SCHEMA_CONTENT_ELEMENTS;
18303
0
  }
18304
  /*
18305
  * Compute the "content type".
18306
  */
18307
0
  if (WXS_IS_RESTRICTION(type)) {
18308
      /*
18309
      * SPEC (3.1) "If <restriction>..."
18310
      * (3.1.1) + (3.1.2) */
18311
0
      if (type->contentType != XML_SCHEMA_CONTENT_EMPTY) {
18312
0
    if (type->flags & XML_SCHEMAS_TYPE_MIXED)
18313
0
        type->contentType = XML_SCHEMA_CONTENT_MIXED;
18314
0
      }
18315
0
  } else {
18316
      /*
18317
      * SPEC (3.2) "If <extension>..."
18318
      */
18319
0
      if (type->contentType == XML_SCHEMA_CONTENT_EMPTY) {
18320
    /*
18321
    * SPEC (3.2.1)
18322
    * "If the `effective content` is empty, then the
18323
    *  {content type} of the [...] base ..."
18324
    */
18325
0
    type->contentType = baseType->contentType;
18326
0
    type->subtypes = baseType->subtypes;
18327
    /*
18328
    * Fixes bug #347316:
18329
    * This is the case when the base type has a simple
18330
    * type definition as content.
18331
    */
18332
0
    type->contentTypeDef = baseType->contentTypeDef;
18333
    /*
18334
    * NOTE that the effective mixed is ignored here.
18335
    */
18336
0
      } else if (baseType->contentType == XML_SCHEMA_CONTENT_EMPTY) {
18337
    /*
18338
    * SPEC (3.2.2)
18339
    */
18340
0
    if (type->flags & XML_SCHEMAS_TYPE_MIXED)
18341
0
        type->contentType = XML_SCHEMA_CONTENT_MIXED;
18342
0
      } else {
18343
    /*
18344
    * SPEC (3.2.3)
18345
    */
18346
0
    if (type->flags & XML_SCHEMAS_TYPE_MIXED)
18347
0
        type->contentType = XML_SCHEMA_CONTENT_MIXED;
18348
        /*
18349
        * "A model group whose {compositor} is sequence and whose
18350
        * {particles} are..."
18351
        */
18352
0
    if ((WXS_TYPE_PARTICLE(type) != NULL) &&
18353
0
        (WXS_TYPE_PARTICLE_TERM(type) != NULL) &&
18354
0
        ((WXS_TYPE_PARTICLE_TERM(type))->type ==
18355
0
      XML_SCHEMA_TYPE_ALL))
18356
0
    {
18357
        /*
18358
        * SPEC cos-all-limited (1)
18359
        */
18360
0
        xmlSchemaCustomErr(ACTXT_CAST pctxt,
18361
      /* TODO: error code */
18362
0
      XML_SCHEMAP_COS_ALL_LIMITED,
18363
0
      WXS_ITEM_NODE(type), NULL,
18364
0
      "The type has an 'all' model group in its "
18365
0
      "{content type} and thus cannot be derived from "
18366
0
      "a non-empty type, since this would produce a "
18367
0
      "'sequence' model group containing the 'all' "
18368
0
      "model group; 'all' model groups are not "
18369
0
      "allowed to appear inside other model groups",
18370
0
      NULL, NULL);
18371
18372
0
    } else if ((WXS_TYPE_PARTICLE(baseType) != NULL) &&
18373
0
        (WXS_TYPE_PARTICLE_TERM(baseType) != NULL) &&
18374
0
        ((WXS_TYPE_PARTICLE_TERM(baseType))->type ==
18375
0
      XML_SCHEMA_TYPE_ALL))
18376
0
    {
18377
        /*
18378
        * SPEC cos-all-limited (1)
18379
        */
18380
0
        xmlSchemaCustomErr(ACTXT_CAST pctxt,
18381
      /* TODO: error code */
18382
0
      XML_SCHEMAP_COS_ALL_LIMITED,
18383
0
      WXS_ITEM_NODE(type), NULL,
18384
0
      "A type cannot be derived by extension from a type "
18385
0
      "which has an 'all' model group in its "
18386
0
      "{content type}, since this would produce a "
18387
0
      "'sequence' model group containing the 'all' "
18388
0
      "model group; 'all' model groups are not "
18389
0
      "allowed to appear inside other model groups",
18390
0
      NULL, NULL);
18391
18392
0
    } else if ((!dummySequence) && (baseType->subtypes != NULL)) {
18393
0
        xmlSchemaTreeItemPtr effectiveContent =
18394
0
      (xmlSchemaTreeItemPtr) type->subtypes;
18395
        /*
18396
        * Create the particle.
18397
        */
18398
0
        particle = xmlSchemaAddParticle(pctxt,
18399
0
      type->node, 1, 1);
18400
0
        if (particle == NULL)
18401
0
      goto exit_failure;
18402
        /*
18403
        * Create the "sequence" model group.
18404
        */
18405
0
        particle->children = (xmlSchemaTreeItemPtr)
18406
0
      xmlSchemaAddModelGroup(pctxt, pctxt->schema,
18407
0
      XML_SCHEMA_TYPE_SEQUENCE, type->node);
18408
0
        if (particle->children == NULL)
18409
0
      goto exit_failure;
18410
0
        WXS_TYPE_CONTENTTYPE(type) = (xmlSchemaTypePtr) particle;
18411
        /*
18412
        * SPEC "the particle of the {content type} of
18413
        * the ... base ..."
18414
        * Create a duplicate of the base type's particle
18415
        * and assign its "term" to it.
18416
        */
18417
0
        particle->children->children =
18418
0
      (xmlSchemaTreeItemPtr) xmlSchemaAddParticle(pctxt,
18419
0
      type->node,
18420
0
      ((xmlSchemaParticlePtr) baseType->subtypes)->minOccurs,
18421
0
      ((xmlSchemaParticlePtr) baseType->subtypes)->maxOccurs);
18422
0
        if (particle->children->children == NULL)
18423
0
      goto exit_failure;
18424
0
        particle = (xmlSchemaParticlePtr)
18425
0
      particle->children->children;
18426
0
        particle->children =
18427
0
      ((xmlSchemaParticlePtr) baseType->subtypes)->children;
18428
        /*
18429
        * SPEC "followed by the `effective content`."
18430
        */
18431
0
        particle->next = effectiveContent;
18432
        /*
18433
        * This all will result in:
18434
        * new-particle
18435
        *   --> new-sequence(
18436
        *         new-particle
18437
        *           --> base-model,
18438
        *         this-particle
18439
        *         --> this-model
18440
        *     )
18441
        */
18442
0
    } else {
18443
        /*
18444
        * This is the case when there is already an empty
18445
        * <sequence> with minOccurs==maxOccurs==1.
18446
        * Just add the base types's content type.
18447
        * NOTE that, although we miss to add an intermediate
18448
        * <sequence>, this should produce no difference to
18449
        * neither the regex compilation of the content model,
18450
        * nor to the complex type constraints.
18451
        */
18452
0
        particle->children->children =
18453
0
      (xmlSchemaTreeItemPtr) baseType->subtypes;
18454
0
    }
18455
0
      }
18456
0
  }
18457
0
    }
18458
    /*
18459
    * Now fixup attribute uses:
18460
    *   - expand attr. group references
18461
    *     - intersect attribute wildcards
18462
    *   - inherit attribute uses of the base type
18463
    *   - inherit or union attr. wildcards if extending
18464
    *   - apply attr. use prohibitions if restricting
18465
    */
18466
0
    res = xmlSchemaFixupTypeAttributeUses(pctxt, type);
18467
0
    HFAILURE HERROR
18468
    /*
18469
    * Apply the complex type component constraints; this will not
18470
    * check attributes, since this is done in
18471
    * xmlSchemaFixupTypeAttributeUses().
18472
    */
18473
0
    res = xmlSchemaCheckCTComponent(pctxt, type);
18474
0
    HFAILURE HERROR
18475
18476
0
    if (olderrs != pctxt->nberrors)
18477
0
  return(pctxt->err);
18478
0
    else
18479
0
  return(0);
18480
18481
0
exit_error:
18482
0
    type->flags |= XML_SCHEMAS_TYPE_INTERNAL_INVALID;
18483
0
    return(pctxt->err);
18484
18485
0
exit_failure:
18486
0
    type->flags |= XML_SCHEMAS_TYPE_INTERNAL_INVALID;
18487
0
    return(-1);
18488
0
}
18489
18490
18491
/**
18492
 * xmlSchemaTypeFixup:
18493
 * @typeDecl:  the schema type definition
18494
 * @ctxt:  the schema parser context
18495
 *
18496
 * Fixes the content model of the type.
18497
 * URGENT TODO: We need an int result!
18498
 */
18499
static int
18500
xmlSchemaTypeFixup(xmlSchemaTypePtr type,
18501
                   xmlSchemaAbstractCtxtPtr actxt)
18502
0
{
18503
0
    if (type == NULL)
18504
0
        return(0);
18505
0
    if (actxt->type != XML_SCHEMA_CTXT_PARSER) {
18506
0
  AERROR_INT("xmlSchemaTypeFixup",
18507
0
      "this function needs a parser context");
18508
0
  return(-1);
18509
0
    }
18510
0
    if (! WXS_IS_TYPE_NOT_FIXED(type))
18511
0
  return(0);
18512
0
    if (type->type == XML_SCHEMA_TYPE_COMPLEX)
18513
0
  return(xmlSchemaFixupComplexType(PCTXT_CAST actxt, type));
18514
0
    else if (type->type == XML_SCHEMA_TYPE_SIMPLE)
18515
0
  return(xmlSchemaFixupSimpleTypeStageTwo(PCTXT_CAST actxt, type));
18516
0
    return(0);
18517
0
}
18518
18519
/**
18520
 * xmlSchemaCheckFacet:
18521
 * @facet:  the facet
18522
 * @typeDecl:  the schema type definition
18523
 * @pctxt:  the schema parser context or NULL
18524
 * @name: the optional name of the type
18525
 *
18526
 * Checks and computes the values of facets.
18527
 *
18528
 * Returns 0 if valid, a positive error code if not valid and
18529
 *         -1 in case of an internal or API error.
18530
 */
18531
int
18532
xmlSchemaCheckFacet(xmlSchemaFacetPtr facet,
18533
                    xmlSchemaTypePtr typeDecl,
18534
                    xmlSchemaParserCtxtPtr pctxt,
18535
        const xmlChar * name ATTRIBUTE_UNUSED)
18536
0
{
18537
0
    int ret = 0, ctxtGiven;
18538
18539
0
    if ((facet == NULL) || (typeDecl == NULL))
18540
0
        return(-1);
18541
    /*
18542
    * TODO: will the parser context be given if used from
18543
    * the relaxNG module?
18544
    */
18545
0
    if (pctxt == NULL)
18546
0
  ctxtGiven = 0;
18547
0
    else
18548
0
  ctxtGiven = 1;
18549
18550
0
    switch (facet->type) {
18551
0
        case XML_SCHEMA_FACET_MININCLUSIVE:
18552
0
        case XML_SCHEMA_FACET_MINEXCLUSIVE:
18553
0
        case XML_SCHEMA_FACET_MAXINCLUSIVE:
18554
0
        case XML_SCHEMA_FACET_MAXEXCLUSIVE:
18555
0
  case XML_SCHEMA_FACET_ENUMERATION: {
18556
                /*
18557
                 * Okay we need to validate the value
18558
                 * at that point.
18559
                 */
18560
0
    xmlSchemaTypePtr base;
18561
18562
    /* 4.3.5.5 Constraints on enumeration Schema Components
18563
    * Schema Component Constraint: enumeration valid restriction
18564
    * It is an `error` if any member of {value} is not in the
18565
    * `value space` of {base type definition}.
18566
    *
18567
    * minInclusive, maxInclusive, minExclusive, maxExclusive:
18568
    * The value `must` be in the
18569
    * `value space` of the `base type`.
18570
    */
18571
    /*
18572
    * This function is intended to deliver a compiled value
18573
    * on the facet. In this implementation of XML Schemata the
18574
    * type holding a facet, won't be a built-in type.
18575
    * Thus to ensure that other API
18576
    * calls (relaxng) do work, if the given type is a built-in
18577
    * type, we will assume that the given built-in type *is
18578
    * already* the base type.
18579
    */
18580
0
    if (typeDecl->type != XML_SCHEMA_TYPE_BASIC) {
18581
0
        base = typeDecl->baseType;
18582
0
        if (base == NULL) {
18583
0
      PERROR_INT("xmlSchemaCheckFacet",
18584
0
          "a type user derived type has no base type");
18585
0
      return (-1);
18586
0
        }
18587
0
    } else
18588
0
        base = typeDecl;
18589
18590
0
    if (! ctxtGiven) {
18591
        /*
18592
        * A context is needed if called from RelaxNG.
18593
        */
18594
0
        pctxt = xmlSchemaNewParserCtxt("*");
18595
0
        if (pctxt == NULL)
18596
0
      return (-1);
18597
0
    }
18598
    /*
18599
    * NOTE: This call does not check the content nodes,
18600
    * since they are not available:
18601
    * facet->node is just the node holding the facet
18602
    * definition, *not* the attribute holding the *value*
18603
    * of the facet.
18604
    */
18605
0
    ret = xmlSchemaVCheckCVCSimpleType(
18606
0
        ACTXT_CAST pctxt, facet->node, base,
18607
0
        facet->value, &(facet->val), 1, 1, 0);
18608
0
                if (ret != 0) {
18609
0
        if (ret < 0) {
18610
      /* No error message for RelaxNG. */
18611
0
      if (ctxtGiven) {
18612
0
          xmlSchemaCustomErr(ACTXT_CAST pctxt,
18613
0
        XML_SCHEMAP_INTERNAL, facet->node, NULL,
18614
0
        "Internal error: xmlSchemaCheckFacet, "
18615
0
        "failed to validate the value '%s' of the "
18616
0
        "facet '%s' against the base type",
18617
0
        facet->value, xmlSchemaFacetTypeToString(facet->type));
18618
0
      }
18619
0
      goto internal_error;
18620
0
        }
18621
0
        ret = XML_SCHEMAP_INVALID_FACET_VALUE;
18622
        /* No error message for RelaxNG. */
18623
0
        if (ctxtGiven) {
18624
0
      xmlChar *str = NULL;
18625
18626
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
18627
0
          ret, facet->node, WXS_BASIC_CAST facet,
18628
0
          "The value '%s' of the facet does not validate "
18629
0
          "against the base type '%s'",
18630
0
          facet->value,
18631
0
          xmlSchemaFormatQName(&str,
18632
0
        base->targetNamespace, base->name));
18633
0
      FREE_AND_NULL(str);
18634
0
        }
18635
0
        goto exit;
18636
0
                } else if (facet->val == NULL) {
18637
0
        if (ctxtGiven) {
18638
0
      PERROR_INT("xmlSchemaCheckFacet",
18639
0
          "value was not computed");
18640
0
        }
18641
        /* TODO */
18642
0
    }
18643
0
                break;
18644
0
            }
18645
0
        case XML_SCHEMA_FACET_PATTERN:
18646
0
            facet->regexp = xmlRegexpCompile(facet->value);
18647
0
            if (facet->regexp == NULL) {
18648
0
    ret = XML_SCHEMAP_REGEXP_INVALID;
18649
    /* No error message for RelaxNG. */
18650
0
    if (ctxtGiven) {
18651
0
        xmlSchemaCustomErr(ACTXT_CAST pctxt,
18652
0
      ret, facet->node, WXS_BASIC_CAST typeDecl,
18653
0
      "The value '%s' of the facet 'pattern' is not a "
18654
0
      "valid regular expression",
18655
0
      facet->value, NULL);
18656
0
    }
18657
0
            }
18658
0
            break;
18659
0
        case XML_SCHEMA_FACET_TOTALDIGITS:
18660
0
        case XML_SCHEMA_FACET_FRACTIONDIGITS:
18661
0
        case XML_SCHEMA_FACET_LENGTH:
18662
0
        case XML_SCHEMA_FACET_MAXLENGTH:
18663
0
        case XML_SCHEMA_FACET_MINLENGTH:
18664
18665
0
      if (facet->type == XML_SCHEMA_FACET_TOTALDIGITS) {
18666
0
    ret = xmlSchemaValidatePredefinedType(
18667
0
        xmlSchemaGetBuiltInType(XML_SCHEMAS_PINTEGER),
18668
0
        facet->value, &(facet->val));
18669
0
      } else {
18670
0
    ret = xmlSchemaValidatePredefinedType(
18671
0
        xmlSchemaGetBuiltInType(XML_SCHEMAS_NNINTEGER),
18672
0
        facet->value, &(facet->val));
18673
0
      }
18674
0
      if (ret != 0) {
18675
0
    if (ret < 0) {
18676
        /* No error message for RelaxNG. */
18677
0
        if (ctxtGiven) {
18678
0
      PERROR_INT("xmlSchemaCheckFacet",
18679
0
          "validating facet value");
18680
0
        }
18681
0
        goto internal_error;
18682
0
    }
18683
0
    ret = XML_SCHEMAP_INVALID_FACET_VALUE;
18684
    /* No error message for RelaxNG. */
18685
0
    if (ctxtGiven) {
18686
        /* error code */
18687
0
        xmlSchemaCustomErr4(ACTXT_CAST pctxt,
18688
0
      ret, facet->node, WXS_BASIC_CAST typeDecl,
18689
0
      "The value '%s' of the facet '%s' is not a valid '%s'",
18690
0
      facet->value,
18691
0
      xmlSchemaFacetTypeToString(facet->type),
18692
0
      (facet->type != XML_SCHEMA_FACET_TOTALDIGITS) ?
18693
0
          BAD_CAST "nonNegativeInteger" :
18694
0
          BAD_CAST "positiveInteger",
18695
0
      NULL);
18696
0
    }
18697
0
      }
18698
0
      break;
18699
18700
0
        case XML_SCHEMA_FACET_WHITESPACE:{
18701
0
                if (xmlStrEqual(facet->value, BAD_CAST "preserve")) {
18702
0
                    facet->whitespace = XML_SCHEMAS_FACET_PRESERVE;
18703
0
                } else if (xmlStrEqual(facet->value, BAD_CAST "replace")) {
18704
0
                    facet->whitespace = XML_SCHEMAS_FACET_REPLACE;
18705
0
                } else if (xmlStrEqual(facet->value, BAD_CAST "collapse")) {
18706
0
                    facet->whitespace = XML_SCHEMAS_FACET_COLLAPSE;
18707
0
                } else {
18708
0
        ret = XML_SCHEMAP_INVALID_FACET_VALUE;
18709
                    /* No error message for RelaxNG. */
18710
0
        if (ctxtGiven) {
18711
      /* error was previously: XML_SCHEMAP_INVALID_WHITE_SPACE */
18712
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
18713
0
          ret, facet->node, WXS_BASIC_CAST typeDecl,
18714
0
          "The value '%s' of the facet 'whitespace' is not "
18715
0
          "valid", facet->value, NULL);
18716
0
                    }
18717
0
                }
18718
0
            }
18719
0
        default:
18720
0
            break;
18721
0
    }
18722
0
exit:
18723
0
    if ((! ctxtGiven) && (pctxt != NULL))
18724
0
  xmlSchemaFreeParserCtxt(pctxt);
18725
0
    return (ret);
18726
0
internal_error:
18727
0
    if ((! ctxtGiven) && (pctxt != NULL))
18728
0
  xmlSchemaFreeParserCtxt(pctxt);
18729
0
    return (-1);
18730
0
}
18731
18732
/**
18733
 * xmlSchemaCheckFacetValues:
18734
 * @typeDecl:  the schema type definition
18735
 * @ctxt:  the schema parser context
18736
 *
18737
 * Checks the default values types, especially for facets
18738
 */
18739
static int
18740
xmlSchemaCheckFacetValues(xmlSchemaTypePtr typeDecl,
18741
        xmlSchemaParserCtxtPtr pctxt)
18742
0
{
18743
0
    int res, olderrs = pctxt->nberrors;
18744
0
    const xmlChar *name = typeDecl->name;
18745
    /*
18746
    * NOTE: It is intended to use the facets list, instead
18747
    * of facetSet.
18748
    */
18749
0
    if (typeDecl->facets != NULL) {
18750
0
  xmlSchemaFacetPtr facet = typeDecl->facets;
18751
18752
  /*
18753
  * Temporarily assign the "schema" to the validation context
18754
  * of the parser context. This is needed for NOTATION validation.
18755
  */
18756
0
  if (pctxt->vctxt == NULL) {
18757
0
      if (xmlSchemaCreateVCtxtOnPCtxt(pctxt) == -1)
18758
0
    return(-1);
18759
0
  }
18760
0
  pctxt->vctxt->schema = pctxt->schema;
18761
0
  while (facet != NULL) {
18762
0
      res = xmlSchemaCheckFacet(facet, typeDecl, pctxt, name);
18763
0
      HFAILURE
18764
0
      facet = facet->next;
18765
0
  }
18766
0
  pctxt->vctxt->schema = NULL;
18767
0
    }
18768
0
    if (olderrs != pctxt->nberrors)
18769
0
  return(pctxt->err);
18770
0
    return(0);
18771
0
exit_failure:
18772
0
    return(-1);
18773
0
}
18774
18775
/**
18776
 * xmlSchemaGetCircModelGrDefRef:
18777
 * @ctxtMGroup: the searched model group
18778
 * @selfMGroup: the second searched model group
18779
 * @particle: the first particle
18780
 *
18781
 * This one is intended to be used by
18782
 * xmlSchemaCheckGroupDefCircular only.
18783
 *
18784
 * Returns the particle with the circular model group definition reference,
18785
 * otherwise NULL.
18786
 */
18787
static xmlSchemaTreeItemPtr
18788
xmlSchemaGetCircModelGrDefRef(xmlSchemaModelGroupDefPtr groupDef,
18789
            xmlSchemaTreeItemPtr particle)
18790
0
{
18791
0
    xmlSchemaTreeItemPtr circ = NULL;
18792
0
    xmlSchemaTreeItemPtr term;
18793
0
    xmlSchemaModelGroupDefPtr gdef;
18794
18795
0
    for (; particle != NULL; particle = particle->next) {
18796
0
  term = particle->children;
18797
0
  if (term == NULL)
18798
0
      continue;
18799
0
  switch (term->type) {
18800
0
      case XML_SCHEMA_TYPE_GROUP:
18801
0
    gdef = (xmlSchemaModelGroupDefPtr) term;
18802
0
    if (gdef == groupDef)
18803
0
        return (particle);
18804
    /*
18805
    * Mark this model group definition to avoid infinite
18806
    * recursion on circular references not yet examined.
18807
    */
18808
0
    if (gdef->flags & XML_SCHEMA_MODEL_GROUP_DEF_MARKED)
18809
0
        continue;
18810
0
    if (gdef->children != NULL) {
18811
0
        gdef->flags |= XML_SCHEMA_MODEL_GROUP_DEF_MARKED;
18812
0
        circ = xmlSchemaGetCircModelGrDefRef(groupDef,
18813
0
      gdef->children->children);
18814
0
        gdef->flags ^= XML_SCHEMA_MODEL_GROUP_DEF_MARKED;
18815
0
        if (circ != NULL)
18816
0
      return (circ);
18817
0
    }
18818
0
    break;
18819
0
      case XML_SCHEMA_TYPE_SEQUENCE:
18820
0
      case XML_SCHEMA_TYPE_CHOICE:
18821
0
      case XML_SCHEMA_TYPE_ALL:
18822
0
    circ = xmlSchemaGetCircModelGrDefRef(groupDef, term->children);
18823
0
    if (circ != NULL)
18824
0
        return (circ);
18825
0
    break;
18826
0
      default:
18827
0
    break;
18828
0
  }
18829
0
    }
18830
0
    return (NULL);
18831
0
}
18832
18833
/**
18834
 * xmlSchemaCheckGroupDefCircular:
18835
 * @item:  the model group definition
18836
 * @ctxt:  the parser context
18837
 * @name:  the name
18838
 *
18839
 * Checks for circular references to model group definitions.
18840
 */
18841
static void
18842
xmlSchemaCheckGroupDefCircular(xmlSchemaModelGroupDefPtr item,
18843
             xmlSchemaParserCtxtPtr ctxt)
18844
0
{
18845
    /*
18846
    * Schema Component Constraint: Model Group Correct
18847
    * 2 Circular groups are disallowed. That is, within the {particles}
18848
    * of a group there must not be at any depth a particle whose {term}
18849
    * is the group itself.
18850
    */
18851
0
    if ((item == NULL) ||
18852
0
  (item->type != XML_SCHEMA_TYPE_GROUP) ||
18853
0
  (item->children == NULL))
18854
0
  return;
18855
0
    {
18856
0
  xmlSchemaTreeItemPtr circ;
18857
18858
0
  circ = xmlSchemaGetCircModelGrDefRef(item, item->children->children);
18859
0
  if (circ != NULL) {
18860
0
      xmlChar *str = NULL;
18861
      /*
18862
      * TODO: The error report is not adequate: this constraint
18863
      * is defined for model groups but not definitions, but since
18864
      * there cannot be any circular model groups without a model group
18865
      * definition (if not using a construction API), we check those
18866
      * definitions only.
18867
      */
18868
0
      xmlSchemaPCustomErr(ctxt,
18869
0
    XML_SCHEMAP_MG_PROPS_CORRECT_2,
18870
0
    NULL, WXS_ITEM_NODE(circ),
18871
0
    "Circular reference to the model group definition '%s' "
18872
0
    "defined", xmlSchemaFormatQName(&str,
18873
0
        item->targetNamespace, item->name));
18874
0
      FREE_AND_NULL(str)
18875
      /*
18876
      * NOTE: We will cut the reference to avoid further
18877
      * confusion of the processor. This is a fatal error.
18878
      */
18879
0
      circ->children = NULL;
18880
0
  }
18881
0
    }
18882
0
}
18883
18884
/**
18885
 * xmlSchemaModelGroupToModelGroupDefFixup:
18886
 * @ctxt:  the parser context
18887
 * @mg:  the model group
18888
 *
18889
 * Assigns the model group of model group definitions to the "term"
18890
 * of the referencing particle.
18891
 * In xmlSchemaResolveModelGroupParticleReferences the model group
18892
 * definitions were assigned to the "term", since needed for the
18893
 * circularity check.
18894
 *
18895
 * Schema Component Constraint:
18896
 *     All Group Limited (cos-all-limited) (1.2)
18897
 */
18898
static void
18899
xmlSchemaModelGroupToModelGroupDefFixup(
18900
    xmlSchemaParserCtxtPtr ctxt ATTRIBUTE_UNUSED,
18901
    xmlSchemaModelGroupPtr mg)
18902
0
{
18903
0
    xmlSchemaParticlePtr particle = WXS_MODELGROUP_PARTICLE(mg);
18904
18905
0
    while (particle != NULL) {
18906
0
  if ((WXS_PARTICLE_TERM(particle) == NULL) ||
18907
0
      ((WXS_PARTICLE_TERM(particle))->type !=
18908
0
    XML_SCHEMA_TYPE_GROUP))
18909
0
  {
18910
0
      particle = WXS_PTC_CAST particle->next;
18911
0
      continue;
18912
0
  }
18913
0
  if (WXS_MODELGROUPDEF_MODEL(WXS_PARTICLE_TERM(particle)) == NULL) {
18914
      /*
18915
      * TODO: Remove the particle.
18916
      */
18917
0
      WXS_PARTICLE_TERM(particle) = NULL;
18918
0
      particle = WXS_PTC_CAST particle->next;
18919
0
      continue;
18920
0
  }
18921
  /*
18922
  * Assign the model group to the {term} of the particle.
18923
  */
18924
0
  WXS_PARTICLE_TERM(particle) =
18925
0
      WXS_TREE_CAST WXS_MODELGROUPDEF_MODEL(WXS_PARTICLE_TERM(particle));
18926
18927
0
  particle = WXS_PTC_CAST particle->next;
18928
0
    }
18929
0
}
18930
18931
/**
18932
 * xmlSchemaCheckAttrGroupCircularRecur:
18933
 * @ctxtGr: the searched attribute group
18934
 * @attr: the current attribute list to be processed
18935
 *
18936
 * This one is intended to be used by
18937
 * xmlSchemaCheckAttrGroupCircular only.
18938
 *
18939
 * Returns the circular attribute group reference, otherwise NULL.
18940
 */
18941
static xmlSchemaQNameRefPtr
18942
xmlSchemaCheckAttrGroupCircularRecur(xmlSchemaAttributeGroupPtr ctxtGr,
18943
             xmlSchemaItemListPtr list)
18944
0
{
18945
0
    xmlSchemaAttributeGroupPtr gr;
18946
0
    xmlSchemaQNameRefPtr ref, circ;
18947
0
    int i;
18948
    /*
18949
    * We will search for an attribute group reference which
18950
    * references the context attribute group.
18951
    */
18952
0
    for (i = 0; i < list->nbItems; i++) {
18953
0
  ref = list->items[i];
18954
0
  if ((ref->type == XML_SCHEMA_EXTRA_QNAMEREF) &&
18955
0
      (ref->itemType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP) &&
18956
0
      (ref->item != NULL))
18957
0
  {
18958
0
      gr = WXS_ATTR_GROUP_CAST ref->item;
18959
0
      if (gr == ctxtGr)
18960
0
    return(ref);
18961
0
      if (gr->flags & XML_SCHEMAS_ATTRGROUP_MARKED)
18962
0
    continue;
18963
      /*
18964
      * Mark as visited to avoid infinite recursion on
18965
      * circular references not yet examined.
18966
      */
18967
0
      if ((gr->attrUses) &&
18968
0
    (gr->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS))
18969
0
      {
18970
0
    gr->flags |= XML_SCHEMAS_ATTRGROUP_MARKED;
18971
0
    circ = xmlSchemaCheckAttrGroupCircularRecur(ctxtGr,
18972
0
        (xmlSchemaItemListPtr) gr->attrUses);
18973
0
    gr->flags ^= XML_SCHEMAS_ATTRGROUP_MARKED;
18974
0
    if (circ != NULL)
18975
0
        return (circ);
18976
0
      }
18977
18978
0
  }
18979
0
    }
18980
0
    return (NULL);
18981
0
}
18982
18983
/**
18984
 * xmlSchemaCheckAttrGroupCircular:
18985
 * attrGr:  the attribute group definition
18986
 * @ctxt:  the parser context
18987
 * @name:  the name
18988
 *
18989
 * Checks for circular references of attribute groups.
18990
 */
18991
static int
18992
xmlSchemaCheckAttrGroupCircular(xmlSchemaAttributeGroupPtr attrGr,
18993
        xmlSchemaParserCtxtPtr ctxt)
18994
0
{
18995
    /*
18996
    * Schema Representation Constraint:
18997
    * Attribute Group Definition Representation OK
18998
    * 3 Circular group reference is disallowed outside <redefine>.
18999
    * That is, unless this element information item's parent is
19000
    * <redefine>, then among the [children], if any, there must
19001
    * not be an <attributeGroup> with ref [attribute] which resolves
19002
    * to the component corresponding to this <attributeGroup>. Indirect
19003
    * circularity is also ruled out. That is, when QName resolution
19004
    * (Schema Document) ($3.15.3) is applied to a `QName` arising from
19005
    * any <attributeGroup>s with a ref [attribute] among the [children],
19006
    * it must not be the case that a `QName` is encountered at any depth
19007
    * which resolves to the component corresponding to this <attributeGroup>.
19008
    */
19009
0
    if (attrGr->attrUses == NULL)
19010
0
  return(0);
19011
0
    else if ((attrGr->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS) == 0)
19012
0
  return(0);
19013
0
    else {
19014
0
  xmlSchemaQNameRefPtr circ;
19015
19016
0
  circ = xmlSchemaCheckAttrGroupCircularRecur(attrGr,
19017
0
      (xmlSchemaItemListPtr) attrGr->attrUses);
19018
0
  if (circ != NULL) {
19019
0
      xmlChar *str = NULL;
19020
      /*
19021
      * TODO: Report the referenced attr group as QName.
19022
      */
19023
0
      xmlSchemaPCustomErr(ctxt,
19024
0
    XML_SCHEMAP_SRC_ATTRIBUTE_GROUP_3,
19025
0
    NULL, WXS_ITEM_NODE(WXS_BASIC_CAST circ),
19026
0
    "Circular reference to the attribute group '%s' "
19027
0
    "defined", xmlSchemaGetComponentQName(&str, attrGr));
19028
0
      FREE_AND_NULL(str);
19029
      /*
19030
      * NOTE: We will cut the reference to avoid further
19031
      * confusion of the processor.
19032
      * BADSPEC TODO: The spec should define how to process in this case.
19033
      */
19034
0
      circ->item = NULL;
19035
0
      return(ctxt->err);
19036
0
  }
19037
0
    }
19038
0
    return(0);
19039
0
}
19040
19041
static int
19042
xmlSchemaAttributeGroupExpandRefs(xmlSchemaParserCtxtPtr pctxt,
19043
          xmlSchemaAttributeGroupPtr attrGr);
19044
19045
/**
19046
 * xmlSchemaExpandAttributeGroupRefs:
19047
 * @pctxt: the parser context
19048
 * @node: the node of the component holding the attribute uses
19049
 * @completeWild: the intersected wildcard to be returned
19050
 * @list: the attribute uses
19051
 *
19052
 * Substitutes contained attribute group references
19053
 * for their attribute uses. Wildcards are intersected.
19054
 * Attribute use prohibitions are removed from the list
19055
 * and returned via the @prohibs list.
19056
 * Pointlessness of attr. prohibs, if a matching attr. decl
19057
 * is existent a well, are checked.
19058
 */
19059
static int
19060
xmlSchemaExpandAttributeGroupRefs(xmlSchemaParserCtxtPtr pctxt,
19061
          xmlSchemaBasicItemPtr item,
19062
          xmlSchemaWildcardPtr *completeWild,
19063
          xmlSchemaItemListPtr list,
19064
          xmlSchemaItemListPtr prohibs)
19065
0
{
19066
0
    xmlSchemaAttributeGroupPtr gr;
19067
0
    xmlSchemaAttributeUsePtr use;
19068
0
    xmlSchemaItemListPtr sublist;
19069
0
    int i, j;
19070
0
    int created = (*completeWild == NULL) ? 0 : 1;
19071
19072
0
    if (prohibs)
19073
0
  prohibs->nbItems = 0;
19074
19075
0
    for (i = 0; i < list->nbItems; i++) {
19076
0
  use = list->items[i];
19077
19078
0
  if (use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) {
19079
0
      if (prohibs == NULL) {
19080
0
    PERROR_INT("xmlSchemaExpandAttributeGroupRefs",
19081
0
        "unexpected attr prohibition found");
19082
0
    return(-1);
19083
0
      }
19084
      /*
19085
      * Remove from attribute uses.
19086
      */
19087
0
      if (xmlSchemaItemListRemove(list, i) == -1)
19088
0
    return(-1);
19089
0
      i--;
19090
      /*
19091
      * Note that duplicate prohibitions were already
19092
      * handled at parsing time.
19093
      */
19094
      /*
19095
      * Add to list of prohibitions.
19096
      */
19097
0
      xmlSchemaItemListAddSize(prohibs, 2, use);
19098
0
      continue;
19099
0
  }
19100
0
  if ((use->type == XML_SCHEMA_EXTRA_QNAMEREF) &&
19101
0
      ((WXS_QNAME_CAST use)->itemType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP))
19102
0
  {
19103
0
      if ((WXS_QNAME_CAST use)->item == NULL)
19104
0
    return(-1);
19105
0
      gr = WXS_ATTR_GROUP_CAST (WXS_QNAME_CAST use)->item;
19106
      /*
19107
      * Expand the referenced attr. group.
19108
      * TODO: remove this, this is done in a previous step, so
19109
      * already done here.
19110
      */
19111
0
      if ((gr->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED) == 0) {
19112
0
    if (xmlSchemaAttributeGroupExpandRefs(pctxt, gr) == -1)
19113
0
        return(-1);
19114
0
      }
19115
      /*
19116
      * Build the 'complete' wildcard; i.e. intersect multiple
19117
      * wildcards.
19118
      */
19119
0
      if (gr->attributeWildcard != NULL) {
19120
0
    if (*completeWild == NULL) {
19121
0
        *completeWild = gr->attributeWildcard;
19122
0
    } else {
19123
0
        if (! created) {
19124
0
      xmlSchemaWildcardPtr tmpWild;
19125
19126
       /*
19127
      * Copy the first encountered wildcard as context,
19128
      * except for the annotation.
19129
      *
19130
      * Although the complete wildcard might not correspond
19131
      * to any node in the schema, we will anchor it on
19132
      * the node of the owner component.
19133
      */
19134
0
      tmpWild =  xmlSchemaAddWildcard(pctxt, pctxt->schema,
19135
0
          XML_SCHEMA_TYPE_ANY_ATTRIBUTE,
19136
0
          WXS_ITEM_NODE(item));
19137
0
      if (tmpWild == NULL)
19138
0
          return(-1);
19139
0
      if (xmlSchemaCloneWildcardNsConstraints(pctxt,
19140
0
          tmpWild, *completeWild) == -1)
19141
0
          return (-1);
19142
0
      tmpWild->processContents = (*completeWild)->processContents;
19143
0
      *completeWild = tmpWild;
19144
0
      created = 1;
19145
0
        }
19146
19147
0
        if (xmlSchemaIntersectWildcards(pctxt, *completeWild,
19148
0
      gr->attributeWildcard) == -1)
19149
0
      return(-1);
19150
0
    }
19151
0
      }
19152
      /*
19153
      * Just remove the reference if the referenced group does not
19154
      * contain any attribute uses.
19155
      */
19156
0
      sublist = ((xmlSchemaItemListPtr) gr->attrUses);
19157
0
      if ((sublist == NULL) || sublist->nbItems == 0) {
19158
0
    if (xmlSchemaItemListRemove(list, i) == -1)
19159
0
        return(-1);
19160
0
    i--;
19161
0
    continue;
19162
0
      }
19163
      /*
19164
      * Add the attribute uses.
19165
      */
19166
0
      list->items[i] = sublist->items[0];
19167
0
      if (sublist->nbItems != 1) {
19168
0
    for (j = 1; j < sublist->nbItems; j++) {
19169
0
        i++;
19170
0
        if (xmlSchemaItemListInsert(list,
19171
0
          sublist->items[j], i) == -1)
19172
0
      return(-1);
19173
0
    }
19174
0
      }
19175
0
  }
19176
19177
0
    }
19178
    /*
19179
    * Handle pointless prohibitions of declared attributes.
19180
    */
19181
0
    if (prohibs && (prohibs->nbItems != 0) && (list->nbItems != 0)) {
19182
0
  xmlSchemaAttributeUseProhibPtr prohib;
19183
19184
0
  for (i = prohibs->nbItems -1; i >= 0; i--) {
19185
0
      prohib = prohibs->items[i];
19186
0
      for (j = 0; j < list->nbItems; j++) {
19187
0
    use = list->items[j];
19188
19189
0
    if ((prohib->name == WXS_ATTRUSE_DECL_NAME(use)) &&
19190
0
        (prohib->targetNamespace == WXS_ATTRUSE_DECL_TNS(use)))
19191
0
    {
19192
0
        xmlChar *str = NULL;
19193
19194
0
        xmlSchemaCustomWarning(ACTXT_CAST pctxt,
19195
0
      XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
19196
0
      prohib->node, NULL,
19197
0
      "Skipping pointless attribute use prohibition "
19198
0
      "'%s', since a corresponding attribute use "
19199
0
      "exists already in the type definition",
19200
0
      xmlSchemaFormatQName(&str,
19201
0
          prohib->targetNamespace, prohib->name),
19202
0
      NULL, NULL);
19203
0
        FREE_AND_NULL(str);
19204
        /*
19205
        * Remove the prohibition.
19206
        */
19207
0
        if (xmlSchemaItemListRemove(prohibs, i) == -1)
19208
0
      return(-1);
19209
0
        break;
19210
0
    }
19211
0
      }
19212
0
  }
19213
0
    }
19214
0
    return(0);
19215
0
}
19216
19217
/**
19218
 * xmlSchemaAttributeGroupExpandRefs:
19219
 * @pctxt:  the parser context
19220
 * @attrGr:  the attribute group definition
19221
 *
19222
 * Computation of:
19223
 * {attribute uses} property
19224
 * {attribute wildcard} property
19225
 *
19226
 * Substitutes contained attribute group references
19227
 * for their attribute uses. Wildcards are intersected.
19228
 */
19229
static int
19230
xmlSchemaAttributeGroupExpandRefs(xmlSchemaParserCtxtPtr pctxt,
19231
          xmlSchemaAttributeGroupPtr attrGr)
19232
0
{
19233
0
    if ((attrGr->attrUses == NULL) ||
19234
0
  (attrGr->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED))
19235
0
  return(0);
19236
19237
0
    attrGr->flags |= XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED;
19238
0
    if (xmlSchemaExpandAttributeGroupRefs(pctxt, WXS_BASIC_CAST attrGr,
19239
0
  &(attrGr->attributeWildcard), attrGr->attrUses, NULL) == -1)
19240
0
  return(-1);
19241
0
    return(0);
19242
0
}
19243
19244
/**
19245
 * xmlSchemaAttributeGroupExpandRefs:
19246
 * @pctxt:  the parser context
19247
 * @attrGr:  the attribute group definition
19248
 *
19249
 * Substitutes contained attribute group references
19250
 * for their attribute uses. Wildcards are intersected.
19251
 *
19252
 * Schema Component Constraint:
19253
 *    Attribute Group Definition Properties Correct (ag-props-correct)
19254
 */
19255
static int
19256
xmlSchemaCheckAGPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
19257
          xmlSchemaAttributeGroupPtr attrGr)
19258
0
{
19259
    /*
19260
    * SPEC ag-props-correct
19261
    * (1) "The values of the properties of an attribute group definition
19262
    * must be as described in the property tableau in The Attribute
19263
    * Group Definition Schema Component ($3.6.1), modulo the impact of
19264
    * Missing Sub-components ($5.3);"
19265
    */
19266
19267
0
    if ((attrGr->attrUses != NULL) &&
19268
0
  (WXS_LIST_CAST attrGr->attrUses)->nbItems > 1)
19269
0
    {
19270
0
  xmlSchemaItemListPtr uses = WXS_LIST_CAST attrGr->attrUses;
19271
0
  xmlSchemaAttributeUsePtr use, tmp;
19272
0
  int i, j, hasId = 0;
19273
19274
0
  for (i = uses->nbItems -1; i >= 0; i--) {
19275
0
      use = uses->items[i];
19276
      /*
19277
      * SPEC ag-props-correct
19278
      * (2) "Two distinct members of the {attribute uses} must not have
19279
      * {attribute declaration}s both of whose {name}s match and whose
19280
      * {target namespace}s are identical."
19281
      */
19282
0
      if (i > 0) {
19283
0
    for (j = i -1; j >= 0; j--) {
19284
0
        tmp = uses->items[j];
19285
0
        if ((WXS_ATTRUSE_DECL_NAME(use) ==
19286
0
      WXS_ATTRUSE_DECL_NAME(tmp)) &&
19287
0
      (WXS_ATTRUSE_DECL_TNS(use) ==
19288
0
      WXS_ATTRUSE_DECL_TNS(tmp)))
19289
0
        {
19290
0
      xmlChar *str = NULL;
19291
19292
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
19293
0
          XML_SCHEMAP_AG_PROPS_CORRECT,
19294
0
          attrGr->node, WXS_BASIC_CAST attrGr,
19295
0
          "Duplicate %s",
19296
0
          xmlSchemaGetComponentDesignation(&str, use),
19297
0
          NULL);
19298
0
      FREE_AND_NULL(str);
19299
      /*
19300
      * Remove the duplicate.
19301
      */
19302
0
      if (xmlSchemaItemListRemove(uses, i) == -1)
19303
0
          return(-1);
19304
0
      goto next_use;
19305
0
        }
19306
0
    }
19307
0
      }
19308
      /*
19309
      * SPEC ag-props-correct
19310
      * (3) "Two distinct members of the {attribute uses} must not have
19311
      * {attribute declaration}s both of whose {type definition}s are or
19312
      * are derived from ID."
19313
      * TODO: Does 'derived' include member-types of unions?
19314
      */
19315
0
      if (WXS_ATTRUSE_TYPEDEF(use) != NULL) {
19316
0
    if (xmlSchemaIsDerivedFromBuiltInType(
19317
0
        WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID))
19318
0
    {
19319
0
        if (hasId) {
19320
0
      xmlChar *str = NULL;
19321
19322
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
19323
0
          XML_SCHEMAP_AG_PROPS_CORRECT,
19324
0
          attrGr->node, WXS_BASIC_CAST attrGr,
19325
0
          "There must not exist more than one attribute "
19326
0
          "declaration of type 'xs:ID' "
19327
0
          "(or derived from 'xs:ID'). The %s violates this "
19328
0
          "constraint",
19329
0
          xmlSchemaGetComponentDesignation(&str, use),
19330
0
          NULL);
19331
0
      FREE_AND_NULL(str);
19332
0
      if (xmlSchemaItemListRemove(uses, i) == -1)
19333
0
          return(-1);
19334
0
        }
19335
0
        hasId = 1;
19336
0
    }
19337
0
      }
19338
0
next_use: {}
19339
0
  }
19340
0
    }
19341
0
    return(0);
19342
0
}
19343
19344
/**
19345
 * xmlSchemaResolveAttrGroupReferences:
19346
 * @attrgrpDecl:  the schema attribute definition
19347
 * @ctxt:  the schema parser context
19348
 * @name:  the attribute name
19349
 *
19350
 * Resolves references to attribute group definitions.
19351
 */
19352
static int
19353
xmlSchemaResolveAttrGroupReferences(xmlSchemaQNameRefPtr ref,
19354
            xmlSchemaParserCtxtPtr ctxt)
19355
0
{
19356
0
    xmlSchemaAttributeGroupPtr group;
19357
19358
0
    if (ref->item != NULL)
19359
0
        return(0);
19360
0
    group = xmlSchemaGetAttributeGroup(ctxt->schema,
19361
0
  ref->name,
19362
0
  ref->targetNamespace);
19363
0
    if (group == NULL) {
19364
0
  xmlSchemaPResCompAttrErr(ctxt,
19365
0
      XML_SCHEMAP_SRC_RESOLVE,
19366
0
      NULL, ref->node,
19367
0
      "ref", ref->name, ref->targetNamespace,
19368
0
      ref->itemType, NULL);
19369
0
  return(ctxt->err);
19370
0
    }
19371
0
    ref->item = WXS_BASIC_CAST group;
19372
0
    return(0);
19373
0
}
19374
19375
/**
19376
 * xmlSchemaCheckAttrPropsCorrect:
19377
 * @item:  an schema attribute declaration/use
19378
 * @ctxt:  a schema parser context
19379
 * @name:  the name of the attribute
19380
 *
19381
 *
19382
 * Schema Component Constraint:
19383
 *    Attribute Declaration Properties Correct (a-props-correct)
19384
 *
19385
 * Validates the value constraints of an attribute declaration/use.
19386
 * NOTE that this needs the simple type definitions to be already
19387
 *   built and checked.
19388
 */
19389
static int
19390
xmlSchemaCheckAttrPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
19391
             xmlSchemaAttributePtr attr)
19392
0
{
19393
19394
    /*
19395
    * SPEC a-props-correct (1)
19396
    * "The values of the properties of an attribute declaration must
19397
    * be as described in the property tableau in The Attribute
19398
    * Declaration Schema Component ($3.2.1), modulo the impact of
19399
    * Missing Sub-components ($5.3)."
19400
    */
19401
19402
0
    if (WXS_ATTR_TYPEDEF(attr) == NULL)
19403
0
  return(0);
19404
19405
0
    if (attr->defValue != NULL) {
19406
0
  int ret;
19407
19408
  /*
19409
  * SPEC a-props-correct (3)
19410
  * "If the {type definition} is or is derived from ID then there
19411
  * must not be a {value constraint}."
19412
  */
19413
0
  if (xmlSchemaIsDerivedFromBuiltInType(
19414
0
      WXS_ATTR_TYPEDEF(attr), XML_SCHEMAS_ID))
19415
0
  {
19416
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
19417
0
    XML_SCHEMAP_A_PROPS_CORRECT_3,
19418
0
    NULL, WXS_BASIC_CAST attr,
19419
0
    "Value constraints are not allowed if the type definition "
19420
0
    "is or is derived from xs:ID",
19421
0
    NULL, NULL);
19422
0
      return(pctxt->err);
19423
0
  }
19424
  /*
19425
  * SPEC a-props-correct (2)
19426
  * "if there is a {value constraint}, the canonical lexical
19427
  * representation of its value must be `valid` with respect
19428
  * to the {type definition} as defined in String Valid ($3.14.4)."
19429
  * TODO: Don't care about the *canonical* stuff here, this requirement
19430
  * will be removed in WXS 1.1 anyway.
19431
  */
19432
0
  ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt,
19433
0
      attr->node, WXS_ATTR_TYPEDEF(attr),
19434
0
      attr->defValue, &(attr->defVal),
19435
0
      1, 1, 0);
19436
0
  if (ret != 0) {
19437
0
      if (ret < 0) {
19438
0
    PERROR_INT("xmlSchemaCheckAttrPropsCorrect",
19439
0
        "calling xmlSchemaVCheckCVCSimpleType()");
19440
0
    return(-1);
19441
0
      }
19442
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
19443
0
    XML_SCHEMAP_A_PROPS_CORRECT_2,
19444
0
    NULL, WXS_BASIC_CAST attr,
19445
0
    "The value of the value constraint is not valid",
19446
0
    NULL, NULL);
19447
0
      return(pctxt->err);
19448
0
  }
19449
0
    }
19450
19451
0
    return(0);
19452
0
}
19453
19454
static xmlSchemaElementPtr
19455
xmlSchemaCheckSubstGroupCircular(xmlSchemaElementPtr elemDecl,
19456
         xmlSchemaElementPtr ancestor)
19457
0
{
19458
0
    xmlSchemaElementPtr ret;
19459
19460
0
    if (WXS_SUBST_HEAD(ancestor) == NULL)
19461
0
  return (NULL);
19462
0
    if (WXS_SUBST_HEAD(ancestor) == elemDecl)
19463
0
  return (ancestor);
19464
19465
0
    if (WXS_SUBST_HEAD(ancestor)->flags & XML_SCHEMAS_ELEM_CIRCULAR)
19466
0
  return (NULL);
19467
0
    WXS_SUBST_HEAD(ancestor)->flags |= XML_SCHEMAS_ELEM_CIRCULAR;
19468
0
    ret = xmlSchemaCheckSubstGroupCircular(elemDecl,
19469
0
  WXS_SUBST_HEAD(ancestor));
19470
0
    WXS_SUBST_HEAD(ancestor)->flags ^= XML_SCHEMAS_ELEM_CIRCULAR;
19471
19472
0
    return (ret);
19473
0
}
19474
19475
/**
19476
 * xmlSchemaCheckElemPropsCorrect:
19477
 * @ctxt:  a schema parser context
19478
 * @decl: the element declaration
19479
 * @name:  the name of the attribute
19480
 *
19481
 * Schema Component Constraint:
19482
 * Element Declaration Properties Correct (e-props-correct)
19483
 *
19484
 * STATUS:
19485
 *   missing: (6)
19486
 */
19487
static int
19488
xmlSchemaCheckElemPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
19489
             xmlSchemaElementPtr elemDecl)
19490
0
{
19491
0
    int ret = 0;
19492
0
    xmlSchemaTypePtr typeDef = WXS_ELEM_TYPEDEF(elemDecl);
19493
    /*
19494
    * SPEC (1) "The values of the properties of an element declaration
19495
    * must be as described in the property tableau in The Element
19496
    * Declaration Schema Component ($3.3.1), modulo the impact of Missing
19497
    * Sub-components ($5.3)."
19498
    */
19499
0
    if (WXS_SUBST_HEAD(elemDecl) != NULL) {
19500
0
  xmlSchemaElementPtr head = WXS_SUBST_HEAD(elemDecl), circ;
19501
19502
0
  xmlSchemaCheckElementDeclComponent(head, pctxt);
19503
  /*
19504
  * SPEC (3) "If there is a non-`absent` {substitution group
19505
  * affiliation}, then {scope} must be global."
19506
  */
19507
0
  if ((elemDecl->flags & XML_SCHEMAS_ELEM_GLOBAL) == 0) {
19508
0
      xmlSchemaPCustomErr(pctxt,
19509
0
    XML_SCHEMAP_E_PROPS_CORRECT_3,
19510
0
    WXS_BASIC_CAST elemDecl, NULL,
19511
0
    "Only global element declarations can have a "
19512
0
    "substitution group affiliation", NULL);
19513
0
      ret = XML_SCHEMAP_E_PROPS_CORRECT_3;
19514
0
  }
19515
  /*
19516
  * TODO: SPEC (6) "Circular substitution groups are disallowed.
19517
  * That is, it must not be possible to return to an element declaration
19518
  * by repeatedly following the {substitution group affiliation}
19519
  * property."
19520
  */
19521
0
  if (head == elemDecl)
19522
0
      circ = head;
19523
0
  else if (WXS_SUBST_HEAD(head) != NULL)
19524
0
      circ = xmlSchemaCheckSubstGroupCircular(head, head);
19525
0
  else
19526
0
      circ = NULL;
19527
0
  if (circ != NULL) {
19528
0
      xmlChar *strA = NULL, *strB = NULL;
19529
19530
0
      xmlSchemaPCustomErrExt(pctxt,
19531
0
    XML_SCHEMAP_E_PROPS_CORRECT_6,
19532
0
    WXS_BASIC_CAST circ, NULL,
19533
0
    "The element declaration '%s' defines a circular "
19534
0
    "substitution group to element declaration '%s'",
19535
0
    xmlSchemaGetComponentQName(&strA, circ),
19536
0
    xmlSchemaGetComponentQName(&strB, head),
19537
0
    NULL);
19538
0
      FREE_AND_NULL(strA)
19539
0
      FREE_AND_NULL(strB)
19540
0
      ret = XML_SCHEMAP_E_PROPS_CORRECT_6;
19541
0
  }
19542
  /*
19543
  * SPEC (4) "If there is a {substitution group affiliation},
19544
  * the {type definition}
19545
  * of the element declaration must be validly derived from the {type
19546
  * definition} of the {substitution group affiliation}, given the value
19547
  * of the {substitution group exclusions} of the {substitution group
19548
  * affiliation}, as defined in Type Derivation OK (Complex) ($3.4.6)
19549
  * (if the {type definition} is complex) or as defined in
19550
  * Type Derivation OK (Simple) ($3.14.6) (if the {type definition} is
19551
  * simple)."
19552
  *
19553
  * NOTE: {substitution group exclusions} means the values of the
19554
  * attribute "final".
19555
  */
19556
19557
0
  if (typeDef != WXS_ELEM_TYPEDEF(WXS_SUBST_HEAD(elemDecl))) {
19558
0
      int set = 0;
19559
19560
0
      if (head->flags & XML_SCHEMAS_ELEM_FINAL_EXTENSION)
19561
0
    set |= SUBSET_EXTENSION;
19562
0
      if (head->flags & XML_SCHEMAS_ELEM_FINAL_RESTRICTION)
19563
0
    set |= SUBSET_RESTRICTION;
19564
19565
0
      if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST pctxt, typeDef,
19566
0
    WXS_ELEM_TYPEDEF(head), set) != 0) {
19567
0
    xmlChar *strA = NULL, *strB = NULL, *strC = NULL;
19568
19569
0
    ret = XML_SCHEMAP_E_PROPS_CORRECT_4;
19570
0
    xmlSchemaPCustomErrExt(pctxt,
19571
0
        XML_SCHEMAP_E_PROPS_CORRECT_4,
19572
0
        WXS_BASIC_CAST elemDecl, NULL,
19573
0
        "The type definition '%s' was "
19574
0
        "either rejected by the substitution group "
19575
0
        "affiliation '%s', or not validly derived from its type "
19576
0
        "definition '%s'",
19577
0
        xmlSchemaGetComponentQName(&strA, typeDef),
19578
0
        xmlSchemaGetComponentQName(&strB, head),
19579
0
        xmlSchemaGetComponentQName(&strC, WXS_ELEM_TYPEDEF(head)));
19580
0
    FREE_AND_NULL(strA)
19581
0
    FREE_AND_NULL(strB)
19582
0
    FREE_AND_NULL(strC)
19583
0
      }
19584
0
  }
19585
0
    }
19586
    /*
19587
    * SPEC (5) "If the {type definition} or {type definition}'s
19588
    * {content type}
19589
    * is or is derived from ID then there must not be a {value constraint}.
19590
    * Note: The use of ID as a type definition for elements goes beyond
19591
    * XML 1.0, and should be avoided if backwards compatibility is desired"
19592
    */
19593
0
    if ((elemDecl->value != NULL) &&
19594
0
  ((WXS_IS_SIMPLE(typeDef) &&
19595
0
    xmlSchemaIsDerivedFromBuiltInType(typeDef, XML_SCHEMAS_ID)) ||
19596
0
   (WXS_IS_COMPLEX(typeDef) &&
19597
0
    WXS_HAS_SIMPLE_CONTENT(typeDef) &&
19598
0
    xmlSchemaIsDerivedFromBuiltInType(typeDef->contentTypeDef,
19599
0
      XML_SCHEMAS_ID)))) {
19600
19601
0
  ret = XML_SCHEMAP_E_PROPS_CORRECT_5;
19602
0
  xmlSchemaPCustomErr(pctxt,
19603
0
      XML_SCHEMAP_E_PROPS_CORRECT_5,
19604
0
      WXS_BASIC_CAST elemDecl, NULL,
19605
0
      "The type definition (or type definition's content type) is or "
19606
0
      "is derived from ID; value constraints are not allowed in "
19607
0
      "conjunction with such a type definition", NULL);
19608
0
    } else if (elemDecl->value != NULL) {
19609
0
  int vcret;
19610
0
  xmlNodePtr node = NULL;
19611
19612
  /*
19613
  * SPEC (2) "If there is a {value constraint}, the canonical lexical
19614
  * representation of its value must be `valid` with respect to the
19615
  * {type definition} as defined in Element Default Valid (Immediate)
19616
  * ($3.3.6)."
19617
  */
19618
0
  if (typeDef == NULL) {
19619
0
      xmlSchemaPErr(pctxt, elemDecl->node,
19620
0
    XML_SCHEMAP_INTERNAL,
19621
0
    "Internal error: xmlSchemaCheckElemPropsCorrect, "
19622
0
    "type is missing... skipping validation of "
19623
0
    "the value constraint", NULL, NULL);
19624
0
      return (-1);
19625
0
  }
19626
0
  if (elemDecl->node != NULL) {
19627
0
      if (elemDecl->flags & XML_SCHEMAS_ELEM_FIXED)
19628
0
    node = (xmlNodePtr) xmlHasProp(elemDecl->node,
19629
0
        BAD_CAST "fixed");
19630
0
      else
19631
0
    node = (xmlNodePtr) xmlHasProp(elemDecl->node,
19632
0
        BAD_CAST "default");
19633
0
  }
19634
0
  vcret = xmlSchemaParseCheckCOSValidDefault(pctxt, node,
19635
0
      typeDef, elemDecl->value, &(elemDecl->defVal));
19636
0
  if (vcret != 0) {
19637
0
      if (vcret < 0) {
19638
0
    PERROR_INT("xmlSchemaElemCheckValConstr",
19639
0
        "failed to validate the value constraint of an "
19640
0
        "element declaration");
19641
0
    return (-1);
19642
0
      }
19643
0
      return (vcret);
19644
0
  }
19645
0
    }
19646
19647
0
    return (ret);
19648
0
}
19649
19650
/**
19651
 * xmlSchemaCheckElemSubstGroup:
19652
 * @ctxt:  a schema parser context
19653
 * @decl: the element declaration
19654
 * @name:  the name of the attribute
19655
 *
19656
 * Schema Component Constraint:
19657
 * Substitution Group (cos-equiv-class)
19658
 *
19659
 * In Libxml2 the subst. groups will be precomputed, in terms of that
19660
 * a list will be built for each subst. group head, holding all direct
19661
 * referents to this head.
19662
 * NOTE that this function needs:
19663
 *   1. circular subst. groups to be checked beforehand
19664
 *   2. the declaration's type to be derived from the head's type
19665
 *
19666
 * STATUS:
19667
 *
19668
 */
19669
static void
19670
xmlSchemaCheckElemSubstGroup(xmlSchemaParserCtxtPtr ctxt,
19671
           xmlSchemaElementPtr elemDecl)
19672
0
{
19673
0
    if ((WXS_SUBST_HEAD(elemDecl) == NULL) ||
19674
  /* SPEC (1) "Its {abstract} is false." */
19675
0
  (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT))
19676
0
  return;
19677
0
    {
19678
0
  xmlSchemaElementPtr head;
19679
0
  xmlSchemaTypePtr headType, type;
19680
0
  int set, methSet;
19681
  /*
19682
  * SPEC (2) "It is validly substitutable for HEAD subject to HEAD's
19683
  * {disallowed substitutions} as the blocking constraint, as defined in
19684
  * Substitution Group OK (Transitive) ($3.3.6)."
19685
  */
19686
0
  for (head = WXS_SUBST_HEAD(elemDecl); head != NULL;
19687
0
      head = WXS_SUBST_HEAD(head)) {
19688
0
      set = 0;
19689
0
      methSet = 0;
19690
      /*
19691
      * The blocking constraints.
19692
      */
19693
0
      if (head->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION)
19694
0
    continue;
19695
0
      headType = head->subtypes;
19696
0
      type = elemDecl->subtypes;
19697
0
      if (headType == type)
19698
0
    goto add_member;
19699
0
      if (head->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION)
19700
0
    set |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
19701
0
      if (head->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION)
19702
0
    set |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
19703
      /*
19704
      * SPEC: Substitution Group OK (Transitive) (2.3)
19705
      * "The set of all {derivation method}s involved in the
19706
      * derivation of D's {type definition} from C's {type definition}
19707
      * does not intersect with the union of the blocking constraint,
19708
      * C's {prohibited substitutions} (if C is complex, otherwise the
19709
      * empty set) and the {prohibited substitutions} (respectively the
19710
      * empty set) of any intermediate {type definition}s in the
19711
      * derivation of D's {type definition} from C's {type definition}."
19712
      */
19713
      /*
19714
      * OPTIMIZE TODO: Optimize this a bit, since, if traversing the
19715
      * subst.head axis, the methSet does not need to be computed for
19716
      * the full depth over and over.
19717
      */
19718
      /*
19719
      * The set of all {derivation method}s involved in the derivation
19720
      */
19721
0
      while ((type != NULL) && (type != headType) &&
19722
0
                   (type != type->baseType)) {
19723
0
    if ((WXS_IS_EXTENSION(type)) &&
19724
0
        ((methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0))
19725
0
        methSet |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
19726
19727
0
    if (WXS_IS_RESTRICTION(type) &&
19728
0
        ((methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0))
19729
0
        methSet |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
19730
19731
0
    type = type->baseType;
19732
0
      }
19733
      /*
19734
      * The {prohibited substitutions} of all intermediate types +
19735
      * the head's type.
19736
      */
19737
0
      type = elemDecl->subtypes->baseType;
19738
0
      while (type != NULL) {
19739
0
    if (WXS_IS_COMPLEX(type)) {
19740
0
        if ((type->flags &
19741
0
          XML_SCHEMAS_TYPE_BLOCK_EXTENSION) &&
19742
0
      ((set & XML_SCHEMAS_TYPE_BLOCK_EXTENSION) == 0))
19743
0
        set |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
19744
0
        if ((type->flags &
19745
0
          XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) &&
19746
0
      ((set & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0))
19747
0
        set |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
19748
0
    } else
19749
0
        break;
19750
0
    if (type == headType)
19751
0
        break;
19752
0
    type = type->baseType;
19753
0
      }
19754
0
      if ((set != 0) &&
19755
0
    (((set & XML_SCHEMAS_TYPE_BLOCK_EXTENSION) &&
19756
0
    (methSet & XML_SCHEMAS_TYPE_BLOCK_EXTENSION)) ||
19757
0
    ((set & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) &&
19758
0
    (methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION)))) {
19759
0
    continue;
19760
0
      }
19761
0
add_member:
19762
0
      xmlSchemaAddElementSubstitutionMember(ctxt, head, elemDecl);
19763
0
      if ((head->flags & XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) == 0)
19764
0
    head->flags |= XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD;
19765
0
  }
19766
0
    }
19767
0
}
19768
19769
#ifdef WXS_ELEM_DECL_CONS_ENABLED /* enable when finished */
19770
/**
19771
 * xmlSchemaCheckElementDeclComponent
19772
 * @pctxt: the schema parser context
19773
 * @ctxtComponent: the context component (an element declaration)
19774
 * @ctxtParticle: the first particle of the context component
19775
 * @searchParticle: the element declaration particle to be analysed
19776
 *
19777
 * Schema Component Constraint: Element Declarations Consistent
19778
 */
19779
static int
19780
xmlSchemaCheckElementDeclConsistent(xmlSchemaParserCtxtPtr pctxt,
19781
            xmlSchemaBasicItemPtr ctxtComponent,
19782
            xmlSchemaParticlePtr ctxtParticle,
19783
            xmlSchemaParticlePtr searchParticle,
19784
            xmlSchemaParticlePtr curParticle,
19785
            int search)
19786
{
19787
    return(0);
19788
19789
    int ret = 0;
19790
    xmlSchemaParticlePtr cur = curParticle;
19791
    if (curParticle == NULL) {
19792
  return(0);
19793
    }
19794
    if (WXS_PARTICLE_TERM(curParticle) == NULL) {
19795
  /*
19796
  * Just return in this case. A missing "term" of the particle
19797
  * might arise due to an invalid "term" component.
19798
  */
19799
  return(0);
19800
    }
19801
    while (cur != NULL) {
19802
  switch (WXS_PARTICLE_TERM(cur)->type) {
19803
      case XML_SCHEMA_TYPE_ANY:
19804
    break;
19805
      case XML_SCHEMA_TYPE_ELEMENT:
19806
    if (search == 0) {
19807
        ret = xmlSchemaCheckElementDeclConsistent(pctxt,
19808
      ctxtComponent, ctxtParticle, cur, ctxtParticle, 1);
19809
        if (ret != 0)
19810
      return(ret);
19811
    } else {
19812
        xmlSchemaElementPtr elem =
19813
      WXS_ELEM_CAST(WXS_PARTICLE_TERM(cur));
19814
        /*
19815
        * SPEC Element Declarations Consistent:
19816
        * "If the {particles} contains, either directly,
19817
        * indirectly (that is, within the {particles} of a
19818
        * contained model group, recursively) or `implicitly`
19819
        * two or more element declaration particles with
19820
        * the same {name} and {target namespace}, then
19821
        * all their type definitions must be the same
19822
        * top-level definition [...]"
19823
        */
19824
        if (xmlStrEqual(WXS_PARTICLE_TERM_AS_ELEM(cur)->name,
19825
          WXS_PARTICLE_TERM_AS_ELEM(searchParticle)->name) &&
19826
      xmlStrEqual(WXS_PARTICLE_TERM_AS_ELEM(cur)->targetNamespace,
19827
          WXS_PARTICLE_TERM_AS_ELEM(searchParticle)->targetNamespace))
19828
        {
19829
      xmlChar *strA = NULL, *strB = NULL;
19830
19831
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
19832
          /* TODO: error code */
19833
          XML_SCHEMAP_COS_NONAMBIG,
19834
          WXS_ITEM_NODE(cur), NULL,
19835
          "In the content model of %s, there are multiple "
19836
          "element declarations for '%s' with different "
19837
          "type definitions",
19838
          xmlSchemaGetComponentDesignation(&strA,
19839
        ctxtComponent),
19840
          xmlSchemaFormatQName(&strB,
19841
        WXS_PARTICLE_TERM_AS_ELEM(cur)->targetNamespace,
19842
        WXS_PARTICLE_TERM_AS_ELEM(cur)->name));
19843
      FREE_AND_NULL(strA);
19844
      FREE_AND_NULL(strB);
19845
      return(XML_SCHEMAP_COS_NONAMBIG);
19846
        }
19847
    }
19848
    break;
19849
      case XML_SCHEMA_TYPE_SEQUENCE: {
19850
    break;
19851
    }
19852
      case XML_SCHEMA_TYPE_CHOICE:{
19853
    /*
19854
    xmlSchemaTreeItemPtr sub;
19855
19856
    sub = WXS_PARTICLE_TERM(particle)->children;  (xmlSchemaParticlePtr)
19857
    while (sub != NULL) {
19858
        ret = xmlSchemaCheckElementDeclConsistent(pctxt, ctxtComponent,
19859
      ctxtParticle, ctxtElem);
19860
        if (ret != 0)
19861
      return(ret);
19862
        sub = sub->next;
19863
    }
19864
    */
19865
    break;
19866
    }
19867
      case XML_SCHEMA_TYPE_ALL:
19868
    break;
19869
      case XML_SCHEMA_TYPE_GROUP:
19870
    break;
19871
      default:
19872
    xmlSchemaInternalErr2(ACTXT_CAST pctxt,
19873
        "xmlSchemaCheckElementDeclConsistent",
19874
        "found unexpected term of type '%s' in content model",
19875
        WXS_ITEM_TYPE_NAME(WXS_PARTICLE_TERM(cur)), NULL);
19876
    return(-1);
19877
  }
19878
  cur = (xmlSchemaParticlePtr) cur->next;
19879
    }
19880
19881
exit:
19882
    return(ret);
19883
}
19884
#endif
19885
19886
/**
19887
 * xmlSchemaCheckElementDeclComponent
19888
 * @item:  an schema element declaration/particle
19889
 * @ctxt:  a schema parser context
19890
 * @name:  the name of the attribute
19891
 *
19892
 * Validates the value constraints of an element declaration.
19893
 * Adds substitution group members.
19894
 */
19895
static void
19896
xmlSchemaCheckElementDeclComponent(xmlSchemaElementPtr elemDecl,
19897
           xmlSchemaParserCtxtPtr ctxt)
19898
0
{
19899
0
    if (elemDecl == NULL)
19900
0
  return;
19901
0
    if (elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_CHECKED)
19902
0
  return;
19903
0
    elemDecl->flags |= XML_SCHEMAS_ELEM_INTERNAL_CHECKED;
19904
0
    if (xmlSchemaCheckElemPropsCorrect(ctxt, elemDecl) == 0) {
19905
  /*
19906
  * Adds substitution group members.
19907
  */
19908
0
  xmlSchemaCheckElemSubstGroup(ctxt, elemDecl);
19909
0
    }
19910
0
}
19911
19912
/**
19913
 * xmlSchemaResolveModelGroupParticleReferences:
19914
 * @particle:  a particle component
19915
 * @ctxt:  a parser context
19916
 *
19917
 * Resolves references of a model group's {particles} to
19918
 * model group definitions and to element declarations.
19919
 */
19920
static void
19921
xmlSchemaResolveModelGroupParticleReferences(
19922
    xmlSchemaParserCtxtPtr ctxt,
19923
    xmlSchemaModelGroupPtr mg)
19924
0
{
19925
0
    xmlSchemaParticlePtr particle = WXS_MODELGROUP_PARTICLE(mg);
19926
0
    xmlSchemaQNameRefPtr ref;
19927
0
    xmlSchemaBasicItemPtr refItem;
19928
19929
    /*
19930
    * URGENT TODO: Test this.
19931
    */
19932
0
    while (particle != NULL) {
19933
0
  if ((WXS_PARTICLE_TERM(particle) == NULL) ||
19934
0
      ((WXS_PARTICLE_TERM(particle))->type !=
19935
0
    XML_SCHEMA_EXTRA_QNAMEREF))
19936
0
  {
19937
0
      goto next_particle;
19938
0
  }
19939
0
  ref = WXS_QNAME_CAST WXS_PARTICLE_TERM(particle);
19940
  /*
19941
  * Resolve the reference.
19942
  * NULL the {term} by default.
19943
  */
19944
0
  particle->children = NULL;
19945
19946
0
  refItem = xmlSchemaGetNamedComponent(ctxt->schema,
19947
0
      ref->itemType, ref->name, ref->targetNamespace);
19948
0
  if (refItem == NULL) {
19949
0
      xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE,
19950
0
    NULL, WXS_ITEM_NODE(particle), "ref", ref->name,
19951
0
    ref->targetNamespace, ref->itemType, NULL);
19952
      /* TODO: remove the particle. */
19953
0
      goto next_particle;
19954
0
  }
19955
0
  if (refItem->type == XML_SCHEMA_TYPE_GROUP) {
19956
0
      if (WXS_MODELGROUPDEF_MODEL(refItem) == NULL)
19957
    /* TODO: remove the particle. */
19958
0
    goto next_particle;
19959
      /*
19960
      * NOTE that we will assign the model group definition
19961
      * itself to the "term" of the particle. This will ease
19962
      * the check for circular model group definitions. After
19963
      * that the "term" will be assigned the model group of the
19964
      * model group definition.
19965
      */
19966
0
      if ((WXS_MODELGROUPDEF_MODEL(refItem))->type ==
19967
0
        XML_SCHEMA_TYPE_ALL) {
19968
    /*
19969
    * SPEC cos-all-limited (1)
19970
    * SPEC cos-all-limited (1.2)
19971
    * "It appears only as the value of one or both of the
19972
    * following properties:"
19973
    * (1.1) "the {model group} property of a model group
19974
    *        definition."
19975
    * (1.2) "the {term} property of a particle [... of] the "
19976
    * {content type} of a complex type definition."
19977
    */
19978
0
    xmlSchemaCustomErr(ACTXT_CAST ctxt,
19979
        /* TODO: error code */
19980
0
        XML_SCHEMAP_COS_ALL_LIMITED,
19981
0
        WXS_ITEM_NODE(particle), NULL,
19982
0
        "A model group definition is referenced, but "
19983
0
        "it contains an 'all' model group, which "
19984
0
        "cannot be contained by model groups",
19985
0
        NULL, NULL);
19986
    /* TODO: remove the particle. */
19987
0
    goto next_particle;
19988
0
      }
19989
0
      particle->children = (xmlSchemaTreeItemPtr) refItem;
19990
0
  } else {
19991
      /*
19992
      * TODO: Are referenced element declarations the only
19993
      * other components we expect here?
19994
      */
19995
0
      particle->children = (xmlSchemaTreeItemPtr) refItem;
19996
0
  }
19997
0
next_particle:
19998
0
  particle = WXS_PTC_CAST particle->next;
19999
0
    }
20000
0
}
20001
20002
static int
20003
xmlSchemaAreValuesEqual(xmlSchemaValPtr x,
20004
           xmlSchemaValPtr y)
20005
0
{
20006
0
    xmlSchemaTypePtr tx, ty, ptx, pty;
20007
0
    int ret;
20008
20009
0
    while (x != NULL) {
20010
  /* Same types. */
20011
0
  tx = xmlSchemaGetBuiltInType(xmlSchemaGetValType(x));
20012
0
  ty = xmlSchemaGetBuiltInType(xmlSchemaGetValType(y));
20013
0
  ptx = xmlSchemaGetPrimitiveType(tx);
20014
0
  pty = xmlSchemaGetPrimitiveType(ty);
20015
  /*
20016
  * (1) if a datatype T' is `derived` by `restriction` from an
20017
  * atomic datatype T then the `value space` of T' is a subset of
20018
  * the `value space` of T. */
20019
  /*
20020
  * (2) if datatypes T' and T'' are `derived` by `restriction`
20021
  * from a common atomic ancestor T then the `value space`s of T'
20022
  * and T'' may overlap.
20023
  */
20024
0
  if (ptx != pty)
20025
0
      return(0);
20026
  /*
20027
  * We assume computed values to be normalized, so do a fast
20028
  * string comparison for string based types.
20029
  */
20030
0
  if ((ptx->builtInType == XML_SCHEMAS_STRING) ||
20031
0
      WXS_IS_ANY_SIMPLE_TYPE(ptx)) {
20032
0
      if (! xmlStrEqual(
20033
0
    xmlSchemaValueGetAsString(x),
20034
0
    xmlSchemaValueGetAsString(y)))
20035
0
    return (0);
20036
0
  } else {
20037
0
      ret = xmlSchemaCompareValuesWhtsp(
20038
0
    x, XML_SCHEMA_WHITESPACE_PRESERVE,
20039
0
    y, XML_SCHEMA_WHITESPACE_PRESERVE);
20040
0
      if (ret == -2)
20041
0
    return(-1);
20042
0
      if (ret != 0)
20043
0
    return(0);
20044
0
  }
20045
  /*
20046
  * Lists.
20047
  */
20048
0
  x = xmlSchemaValueGetNext(x);
20049
0
  if (x != NULL) {
20050
0
      y = xmlSchemaValueGetNext(y);
20051
0
      if (y == NULL)
20052
0
    return (0);
20053
0
  } else if (xmlSchemaValueGetNext(y) != NULL)
20054
0
      return (0);
20055
0
  else
20056
0
      return (1);
20057
0
    }
20058
0
    return (0);
20059
0
}
20060
20061
/**
20062
 * xmlSchemaResolveAttrUseReferences:
20063
 * @item:  an attribute use
20064
 * @ctxt:  a parser context
20065
 *
20066
 * Resolves the referenced attribute declaration.
20067
 */
20068
static int
20069
xmlSchemaResolveAttrUseReferences(xmlSchemaAttributeUsePtr ause,
20070
          xmlSchemaParserCtxtPtr ctxt)
20071
0
{
20072
0
    if ((ctxt == NULL) || (ause == NULL))
20073
0
  return(-1);
20074
0
    if ((ause->attrDecl == NULL) ||
20075
0
  (ause->attrDecl->type != XML_SCHEMA_EXTRA_QNAMEREF))
20076
0
  return(0);
20077
20078
0
    {
20079
0
  xmlSchemaQNameRefPtr ref = WXS_QNAME_CAST ause->attrDecl;
20080
20081
  /*
20082
  * TODO: Evaluate, what errors could occur if the declaration is not
20083
  * found.
20084
  */
20085
0
  ause->attrDecl = xmlSchemaGetAttributeDecl(ctxt->schema,
20086
0
      ref->name, ref->targetNamespace);
20087
0
        if (ause->attrDecl == NULL) {
20088
0
      xmlSchemaPResCompAttrErr(ctxt,
20089
0
    XML_SCHEMAP_SRC_RESOLVE,
20090
0
    WXS_BASIC_CAST ause, ause->node,
20091
0
    "ref", ref->name, ref->targetNamespace,
20092
0
    XML_SCHEMA_TYPE_ATTRIBUTE, NULL);
20093
0
            return(ctxt->err);;
20094
0
        }
20095
0
    }
20096
0
    return(0);
20097
0
}
20098
20099
/**
20100
 * xmlSchemaCheckAttrUsePropsCorrect:
20101
 * @ctxt:  a parser context
20102
 * @use:  an attribute use
20103
 *
20104
 * Schema Component Constraint:
20105
 * Attribute Use Correct (au-props-correct)
20106
 *
20107
 */
20108
static int
20109
xmlSchemaCheckAttrUsePropsCorrect(xmlSchemaParserCtxtPtr ctxt,
20110
           xmlSchemaAttributeUsePtr use)
20111
0
{
20112
0
    if ((ctxt == NULL) || (use == NULL))
20113
0
  return(-1);
20114
0
    if ((use->defValue == NULL) || (WXS_ATTRUSE_DECL(use) == NULL) ||
20115
0
  ((WXS_ATTRUSE_DECL(use))->type != XML_SCHEMA_TYPE_ATTRIBUTE))
20116
0
  return(0);
20117
20118
    /*
20119
    * SPEC au-props-correct (1)
20120
    * "The values of the properties of an attribute use must be as
20121
    * described in the property tableau in The Attribute Use Schema
20122
    * Component ($3.5.1), modulo the impact of Missing
20123
    * Sub-components ($5.3)."
20124
    */
20125
20126
0
    if (((WXS_ATTRUSE_DECL(use))->defValue != NULL) &&
20127
0
  ((WXS_ATTRUSE_DECL(use))->flags & XML_SCHEMAS_ATTR_FIXED) &&
20128
0
        ((use->flags & XML_SCHEMA_ATTR_USE_FIXED) == 0))
20129
0
    {
20130
0
  xmlSchemaPCustomErr(ctxt,
20131
0
      XML_SCHEMAP_AU_PROPS_CORRECT_2,
20132
0
      WXS_BASIC_CAST use, NULL,
20133
0
      "The attribute declaration has a 'fixed' value constraint "
20134
0
      ", thus the attribute use must also have a 'fixed' value "
20135
0
      "constraint",
20136
0
      NULL);
20137
0
  return(ctxt->err);
20138
0
    }
20139
    /*
20140
    * Compute and check the value constraint's value.
20141
    */
20142
0
    if ((use->defVal != NULL) && (WXS_ATTRUSE_TYPEDEF(use) != NULL)) {
20143
0
  int ret;
20144
  /*
20145
  * TODO: The spec seems to be missing a check of the
20146
  * value constraint of the attribute use. We will do it here.
20147
  */
20148
  /*
20149
  * SPEC a-props-correct (3)
20150
  */
20151
0
  if (xmlSchemaIsDerivedFromBuiltInType(
20152
0
      WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID))
20153
0
  {
20154
0
      xmlSchemaCustomErr(ACTXT_CAST ctxt,
20155
0
    XML_SCHEMAP_AU_PROPS_CORRECT,
20156
0
    NULL, WXS_BASIC_CAST use,
20157
0
    "Value constraints are not allowed if the type definition "
20158
0
    "is or is derived from xs:ID",
20159
0
    NULL, NULL);
20160
0
      return(ctxt->err);
20161
0
  }
20162
20163
0
  ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST ctxt,
20164
0
      use->node, WXS_ATTRUSE_TYPEDEF(use),
20165
0
      use->defValue, &(use->defVal),
20166
0
      1, 1, 0);
20167
0
  if (ret != 0) {
20168
0
      if (ret < 0) {
20169
0
    PERROR_INT2("xmlSchemaCheckAttrUsePropsCorrect",
20170
0
        "calling xmlSchemaVCheckCVCSimpleType()");
20171
0
    return(-1);
20172
0
      }
20173
0
      xmlSchemaCustomErr(ACTXT_CAST ctxt,
20174
0
    XML_SCHEMAP_AU_PROPS_CORRECT,
20175
0
    NULL, WXS_BASIC_CAST use,
20176
0
    "The value of the value constraint is not valid",
20177
0
    NULL, NULL);
20178
0
      return(ctxt->err);
20179
0
  }
20180
0
    }
20181
    /*
20182
    * SPEC au-props-correct (2)
20183
    * "If the {attribute declaration} has a fixed
20184
    * {value constraint}, then if the attribute use itself has a
20185
    * {value constraint}, it must also be fixed and its value must match
20186
    * that of the {attribute declaration}'s {value constraint}."
20187
    */
20188
0
    if (((WXS_ATTRUSE_DECL(use))->defVal != NULL) &&
20189
0
  (((WXS_ATTRUSE_DECL(use))->flags & XML_SCHEMA_ATTR_USE_FIXED) == 0))
20190
0
    {
20191
0
  if (! xmlSchemaAreValuesEqual(use->defVal,
20192
0
    (WXS_ATTRUSE_DECL(use))->defVal))
20193
0
  {
20194
0
      xmlSchemaPCustomErr(ctxt,
20195
0
    XML_SCHEMAP_AU_PROPS_CORRECT_2,
20196
0
    WXS_BASIC_CAST use, NULL,
20197
0
    "The 'fixed' value constraint of the attribute use "
20198
0
    "must match the attribute declaration's value "
20199
0
    "constraint '%s'",
20200
0
    (WXS_ATTRUSE_DECL(use))->defValue);
20201
0
  }
20202
0
  return(ctxt->err);
20203
0
    }
20204
0
    return(0);
20205
0
}
20206
20207
20208
20209
20210
/**
20211
 * xmlSchemaResolveAttrTypeReferences:
20212
 * @item:  an attribute declaration
20213
 * @ctxt:  a parser context
20214
 *
20215
 * Resolves the referenced type definition component.
20216
 */
20217
static int
20218
xmlSchemaResolveAttrTypeReferences(xmlSchemaAttributePtr item,
20219
           xmlSchemaParserCtxtPtr ctxt)
20220
0
{
20221
    /*
20222
    * The simple type definition corresponding to the <simpleType> element
20223
    * information item in the [children], if present, otherwise the simple
20224
    * type definition `resolved` to by the `actual value` of the type
20225
    * [attribute], if present, otherwise the `simple ur-type definition`.
20226
    */
20227
0
    if (item->flags & XML_SCHEMAS_ATTR_INTERNAL_RESOLVED)
20228
0
  return(0);
20229
0
    item->flags |= XML_SCHEMAS_ATTR_INTERNAL_RESOLVED;
20230
0
    if (item->subtypes != NULL)
20231
0
        return(0);
20232
0
    if (item->typeName != NULL) {
20233
0
        xmlSchemaTypePtr type;
20234
20235
0
  type = xmlSchemaGetType(ctxt->schema, item->typeName,
20236
0
      item->typeNs);
20237
0
  if ((type == NULL) || (! WXS_IS_SIMPLE(type))) {
20238
0
      xmlSchemaPResCompAttrErr(ctxt,
20239
0
    XML_SCHEMAP_SRC_RESOLVE,
20240
0
    WXS_BASIC_CAST item, item->node,
20241
0
    "type", item->typeName, item->typeNs,
20242
0
    XML_SCHEMA_TYPE_SIMPLE, NULL);
20243
0
      return(ctxt->err);
20244
0
  } else
20245
0
      item->subtypes = type;
20246
20247
0
    } else {
20248
  /*
20249
  * The type defaults to the xs:anySimpleType.
20250
  */
20251
0
  item->subtypes = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
20252
0
    }
20253
0
    return(0);
20254
0
}
20255
20256
/**
20257
 * xmlSchemaResolveIDCKeyReferences:
20258
 * @idc:  the identity-constraint definition
20259
 * @ctxt:  the schema parser context
20260
 * @name:  the attribute name
20261
 *
20262
 * Resolve keyRef references to key/unique IDCs.
20263
 * Schema Component Constraint:
20264
 *   Identity-constraint Definition Properties Correct (c-props-correct)
20265
 */
20266
static int
20267
xmlSchemaResolveIDCKeyReferences(xmlSchemaIDCPtr idc,
20268
        xmlSchemaParserCtxtPtr pctxt)
20269
0
{
20270
0
    if (idc->type != XML_SCHEMA_TYPE_IDC_KEYREF)
20271
0
        return(0);
20272
0
    if (idc->ref->name != NULL) {
20273
0
  idc->ref->item = (xmlSchemaBasicItemPtr)
20274
0
      xmlSchemaGetIDC(pctxt->schema, idc->ref->name,
20275
0
    idc->ref->targetNamespace);
20276
0
        if (idc->ref->item == NULL) {
20277
      /*
20278
      * TODO: It is actually not an error to fail to resolve
20279
      * at this stage. BUT we need to be that strict!
20280
      */
20281
0
      xmlSchemaPResCompAttrErr(pctxt,
20282
0
    XML_SCHEMAP_SRC_RESOLVE,
20283
0
    WXS_BASIC_CAST idc, idc->node,
20284
0
    "refer", idc->ref->name,
20285
0
    idc->ref->targetNamespace,
20286
0
    XML_SCHEMA_TYPE_IDC_KEY, NULL);
20287
0
            return(pctxt->err);
20288
0
  } else if (idc->ref->item->type == XML_SCHEMA_TYPE_IDC_KEYREF) {
20289
      /*
20290
      * SPEC c-props-correct (1)
20291
      */
20292
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
20293
0
    XML_SCHEMAP_C_PROPS_CORRECT,
20294
0
    NULL, WXS_BASIC_CAST idc,
20295
0
    "The keyref references a keyref",
20296
0
    NULL, NULL);
20297
0
      idc->ref->item = NULL;
20298
0
      return(pctxt->err);
20299
0
  } else {
20300
0
      if (idc->nbFields !=
20301
0
    ((xmlSchemaIDCPtr) idc->ref->item)->nbFields) {
20302
0
    xmlChar *str = NULL;
20303
0
    xmlSchemaIDCPtr refer;
20304
20305
0
    refer = (xmlSchemaIDCPtr) idc->ref->item;
20306
    /*
20307
    * SPEC c-props-correct(2)
20308
    * "If the {identity-constraint category} is keyref,
20309
    * the cardinality of the {fields} must equal that of
20310
    * the {fields} of the {referenced key}.
20311
    */
20312
0
    xmlSchemaCustomErr(ACTXT_CAST pctxt,
20313
0
        XML_SCHEMAP_C_PROPS_CORRECT,
20314
0
        NULL, WXS_BASIC_CAST idc,
20315
0
        "The cardinality of the keyref differs from the "
20316
0
        "cardinality of the referenced key/unique '%s'",
20317
0
        xmlSchemaFormatQName(&str, refer->targetNamespace,
20318
0
      refer->name),
20319
0
        NULL);
20320
0
    FREE_AND_NULL(str)
20321
0
    return(pctxt->err);
20322
0
      }
20323
0
  }
20324
0
    }
20325
0
    return(0);
20326
0
}
20327
20328
static int
20329
xmlSchemaResolveAttrUseProhibReferences(xmlSchemaAttributeUseProhibPtr prohib,
20330
               xmlSchemaParserCtxtPtr pctxt)
20331
0
{
20332
0
    if (xmlSchemaGetAttributeDecl(pctxt->schema, prohib->name,
20333
0
  prohib->targetNamespace) == NULL) {
20334
20335
0
  xmlSchemaPResCompAttrErr(pctxt,
20336
0
      XML_SCHEMAP_SRC_RESOLVE,
20337
0
      NULL, prohib->node,
20338
0
      "ref", prohib->name, prohib->targetNamespace,
20339
0
      XML_SCHEMA_TYPE_ATTRIBUTE, NULL);
20340
0
  return(XML_SCHEMAP_SRC_RESOLVE);
20341
0
    }
20342
0
    return(0);
20343
0
}
20344
20345
0
#define WXS_REDEFINED_TYPE(c) \
20346
0
(((xmlSchemaTypePtr) item)->flags & XML_SCHEMAS_TYPE_REDEFINED)
20347
20348
0
#define WXS_REDEFINED_MODEL_GROUP_DEF(c) \
20349
0
(((xmlSchemaModelGroupDefPtr) item)->flags & XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED)
20350
20351
0
#define WXS_REDEFINED_ATTR_GROUP(c) \
20352
0
(((xmlSchemaAttributeGroupPtr) item)->flags & XML_SCHEMAS_ATTRGROUP_REDEFINED)
20353
20354
static int
20355
xmlSchemaCheckSRCRedefineFirst(xmlSchemaParserCtxtPtr pctxt)
20356
0
{
20357
0
    int err = 0;
20358
0
    xmlSchemaRedefPtr redef = WXS_CONSTRUCTOR(pctxt)->redefs;
20359
0
    xmlSchemaBasicItemPtr prev, item;
20360
0
    int wasRedefined;
20361
20362
0
    if (redef == NULL)
20363
0
  return(0);
20364
20365
0
    do {
20366
0
  item = redef->item;
20367
  /*
20368
  * First try to locate the redefined component in the
20369
  * schema graph starting with the redefined schema.
20370
  * NOTE: According to this schema bug entry:
20371
  *   http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005OctDec/0019.html
20372
  *   it's not clear if the referenced component needs to originate
20373
  *   from the <redefine>d schema _document_ or the schema; the latter
20374
  *   would include all imported and included sub-schemas of the
20375
  *   <redefine>d schema. Currently the latter approach is used.
20376
  *   SUPPLEMENT: It seems that the WG moves towards the latter
20377
  *   approach, so we are doing it right.
20378
  *
20379
  */
20380
0
  prev = xmlSchemaFindRedefCompInGraph(
20381
0
      redef->targetBucket, item->type,
20382
0
      redef->refName, redef->refTargetNs);
20383
0
  if (prev == NULL) {
20384
0
      xmlChar *str = NULL;
20385
0
      xmlNodePtr node;
20386
20387
      /*
20388
      * SPEC src-redefine:
20389
      * (6.2.1) "The `actual value` of its own name attribute plus
20390
      * target namespace must successfully `resolve` to a model
20391
      * group definition in I."
20392
      * (7.2.1) "The `actual value` of its own name attribute plus
20393
      * target namespace must successfully `resolve` to an attribute
20394
      * group definition in I."
20395
20396
      *
20397
      * Note that, if we are redefining with the use of references
20398
      * to components, the spec assumes the src-resolve to be used;
20399
      * but this won't assure that we search only *inside* the
20400
      * redefined schema.
20401
      */
20402
0
      if (redef->reference)
20403
0
    node = WXS_ITEM_NODE(redef->reference);
20404
0
      else
20405
0
    node = WXS_ITEM_NODE(item);
20406
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
20407
    /*
20408
    * TODO: error code.
20409
    * Probably XML_SCHEMAP_SRC_RESOLVE, if this is using the
20410
    * reference kind.
20411
    */
20412
0
    XML_SCHEMAP_SRC_REDEFINE, node, NULL,
20413
0
    "The %s '%s' to be redefined could not be found in "
20414
0
    "the redefined schema",
20415
0
    WXS_ITEM_TYPE_NAME(item),
20416
0
    xmlSchemaFormatQName(&str, redef->refTargetNs,
20417
0
        redef->refName));
20418
0
      FREE_AND_NULL(str);
20419
0
      err = pctxt->err;
20420
0
      redef = redef->next;
20421
0
      continue;
20422
0
  }
20423
  /*
20424
  * TODO: Obtaining and setting the redefinition state is really
20425
  * clumsy.
20426
  */
20427
0
  wasRedefined = 0;
20428
0
  switch (item->type) {
20429
0
      case XML_SCHEMA_TYPE_COMPLEX:
20430
0
      case XML_SCHEMA_TYPE_SIMPLE:
20431
0
    if ((WXS_TYPE_CAST prev)->flags &
20432
0
        XML_SCHEMAS_TYPE_REDEFINED)
20433
0
    {
20434
0
        wasRedefined = 1;
20435
0
        break;
20436
0
    }
20437
    /* Mark it as redefined. */
20438
0
    (WXS_TYPE_CAST prev)->flags |= XML_SCHEMAS_TYPE_REDEFINED;
20439
    /*
20440
    * Assign the redefined type to the
20441
    * base type of the redefining type.
20442
    * TODO: How
20443
    */
20444
0
    ((xmlSchemaTypePtr) item)->baseType =
20445
0
        (xmlSchemaTypePtr) prev;
20446
0
    break;
20447
0
      case XML_SCHEMA_TYPE_GROUP:
20448
0
    if ((WXS_MODEL_GROUPDEF_CAST prev)->flags &
20449
0
        XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED)
20450
0
    {
20451
0
        wasRedefined = 1;
20452
0
        break;
20453
0
    }
20454
    /* Mark it as redefined. */
20455
0
    (WXS_MODEL_GROUPDEF_CAST prev)->flags |=
20456
0
        XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED;
20457
0
    if (redef->reference != NULL) {
20458
        /*
20459
        * Overwrite the QName-reference with the
20460
        * referenced model group def.
20461
        */
20462
0
        (WXS_PTC_CAST redef->reference)->children =
20463
0
      WXS_TREE_CAST prev;
20464
0
    }
20465
0
    redef->target = prev;
20466
0
    break;
20467
0
      case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
20468
0
    if ((WXS_ATTR_GROUP_CAST prev)->flags &
20469
0
        XML_SCHEMAS_ATTRGROUP_REDEFINED)
20470
0
    {
20471
0
        wasRedefined = 1;
20472
0
        break;
20473
0
    }
20474
0
    (WXS_ATTR_GROUP_CAST prev)->flags |=
20475
0
        XML_SCHEMAS_ATTRGROUP_REDEFINED;
20476
0
    if (redef->reference != NULL) {
20477
        /*
20478
        * Assign the redefined attribute group to the
20479
        * QName-reference component.
20480
        * This is the easy case, since we will just
20481
        * expand the redefined group.
20482
        */
20483
0
        (WXS_QNAME_CAST redef->reference)->item = prev;
20484
0
        redef->target = NULL;
20485
0
    } else {
20486
        /*
20487
        * This is the complicated case: we need
20488
        * to apply src-redefine (7.2.2) at a later
20489
        * stage, i.e. when attribute group references
20490
        * have been expanded and simple types have
20491
        * been fixed.
20492
        */
20493
0
        redef->target = prev;
20494
0
    }
20495
0
    break;
20496
0
      default:
20497
0
    PERROR_INT("xmlSchemaResolveRedefReferences",
20498
0
        "Unexpected redefined component type");
20499
0
    return(-1);
20500
0
  }
20501
0
  if (wasRedefined) {
20502
0
      xmlChar *str = NULL;
20503
0
      xmlNodePtr node;
20504
20505
0
      if (redef->reference)
20506
0
    node = WXS_ITEM_NODE(redef->reference);
20507
0
      else
20508
0
    node = WXS_ITEM_NODE(redef->item);
20509
20510
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
20511
    /* TODO: error code. */
20512
0
    XML_SCHEMAP_SRC_REDEFINE,
20513
0
    node, NULL,
20514
0
    "The referenced %s was already redefined. Multiple "
20515
0
    "redefinition of the same component is not supported",
20516
0
    xmlSchemaGetComponentDesignation(&str, prev),
20517
0
    NULL);
20518
0
      FREE_AND_NULL(str)
20519
0
      err = pctxt->err;
20520
0
      redef = redef->next;
20521
0
      continue;
20522
0
  }
20523
0
  redef = redef->next;
20524
0
    } while (redef != NULL);
20525
20526
0
    return(err);
20527
0
}
20528
20529
static int
20530
xmlSchemaCheckSRCRedefineSecond(xmlSchemaParserCtxtPtr pctxt)
20531
0
{
20532
0
    int err = 0;
20533
0
    xmlSchemaRedefPtr redef = WXS_CONSTRUCTOR(pctxt)->redefs;
20534
0
    xmlSchemaBasicItemPtr item;
20535
20536
0
    if (redef == NULL)
20537
0
  return(0);
20538
20539
0
    do {
20540
0
  if (redef->target == NULL) {
20541
0
      redef = redef->next;
20542
0
      continue;
20543
0
  }
20544
0
  item = redef->item;
20545
20546
0
  switch (item->type) {
20547
0
      case XML_SCHEMA_TYPE_SIMPLE:
20548
0
      case XML_SCHEMA_TYPE_COMPLEX:
20549
    /*
20550
    * Since the spec wants the {name} of the redefined
20551
    * type to be 'absent', we'll NULL it.
20552
    */
20553
0
    (WXS_TYPE_CAST redef->target)->name = NULL;
20554
20555
    /*
20556
    * TODO: Seems like there's nothing more to do. The normal
20557
    * inheritance mechanism is used. But not 100% sure.
20558
    */
20559
0
    break;
20560
0
      case XML_SCHEMA_TYPE_GROUP:
20561
    /*
20562
    * URGENT TODO:
20563
    * SPEC src-redefine:
20564
    * (6.2.2) "The {model group} of the model group definition
20565
    * which corresponds to it per XML Representation of Model
20566
    * Group Definition Schema Components ($3.7.2) must be a
20567
    * `valid restriction` of the {model group} of that model
20568
    * group definition in I, as defined in Particle Valid
20569
    * (Restriction) ($3.9.6)."
20570
    */
20571
0
    break;
20572
0
      case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
20573
    /*
20574
    * SPEC src-redefine:
20575
    * (7.2.2) "The {attribute uses} and {attribute wildcard} of
20576
    * the attribute group definition which corresponds to it
20577
    * per XML Representation of Attribute Group Definition Schema
20578
    * Components ($3.6.2) must be `valid restrictions` of the
20579
    * {attribute uses} and {attribute wildcard} of that attribute
20580
    * group definition in I, as defined in clause 2, clause 3 and
20581
    * clause 4 of Derivation Valid (Restriction, Complex)
20582
    * ($3.4.6) (where references to the base type definition are
20583
    * understood as references to the attribute group definition
20584
    * in I)."
20585
    */
20586
0
    err = xmlSchemaCheckDerivationOKRestriction2to4(pctxt,
20587
0
        XML_SCHEMA_ACTION_REDEFINE,
20588
0
        item, redef->target,
20589
0
        (WXS_ATTR_GROUP_CAST item)->attrUses,
20590
0
        (WXS_ATTR_GROUP_CAST redef->target)->attrUses,
20591
0
        (WXS_ATTR_GROUP_CAST item)->attributeWildcard,
20592
0
        (WXS_ATTR_GROUP_CAST redef->target)->attributeWildcard);
20593
0
    if (err == -1)
20594
0
        return(-1);
20595
0
    break;
20596
0
      default:
20597
0
    break;
20598
0
  }
20599
0
  redef = redef->next;
20600
0
    } while (redef != NULL);
20601
0
    return(0);
20602
0
}
20603
20604
20605
static int
20606
xmlSchemaAddComponents(xmlSchemaParserCtxtPtr pctxt,
20607
           xmlSchemaBucketPtr bucket)
20608
0
{
20609
0
    xmlSchemaBasicItemPtr item;
20610
0
    int err;
20611
0
    xmlHashTablePtr *table;
20612
0
    const xmlChar *name;
20613
0
    int i;
20614
20615
0
#define WXS_GET_GLOBAL_HASH(c, slot) { \
20616
0
    if (WXS_IS_BUCKET_IMPMAIN((c)->type)) \
20617
0
  table = &(WXS_IMPBUCKET((c))->schema->slot); \
20618
0
    else \
20619
0
  table = &(WXS_INCBUCKET((c))->ownerImport->schema->slot); }
20620
20621
    /*
20622
    * Add global components to the schema's hash tables.
20623
    * This is the place where duplicate components will be
20624
    * detected.
20625
    * TODO: I think normally we should support imports of the
20626
    *   same namespace from multiple locations. We don't do currently,
20627
    *   but if we do then according to:
20628
    *   http://www.w3.org/Bugs/Public/show_bug.cgi?id=2224
20629
    *   we would need, if imported directly, to import redefined
20630
    *   components as well to be able to catch clashing components.
20631
    *   (I hope I'll still know what this means after some months :-()
20632
    */
20633
0
    if (bucket == NULL)
20634
0
  return(-1);
20635
0
    if (bucket->flags & XML_SCHEMA_BUCKET_COMPS_ADDED)
20636
0
  return(0);
20637
0
    bucket->flags |= XML_SCHEMA_BUCKET_COMPS_ADDED;
20638
20639
0
    for (i = 0; i < bucket->globals->nbItems; i++) {
20640
0
  item = bucket->globals->items[i];
20641
0
  table = NULL;
20642
0
  switch (item->type) {
20643
0
      case XML_SCHEMA_TYPE_COMPLEX:
20644
0
      case XML_SCHEMA_TYPE_SIMPLE:
20645
0
    if (WXS_REDEFINED_TYPE(item))
20646
0
        continue;
20647
0
    name = (WXS_TYPE_CAST item)->name;
20648
0
    WXS_GET_GLOBAL_HASH(bucket, typeDecl)
20649
0
    break;
20650
0
      case XML_SCHEMA_TYPE_ELEMENT:
20651
0
    name = (WXS_ELEM_CAST item)->name;
20652
0
    WXS_GET_GLOBAL_HASH(bucket, elemDecl)
20653
0
    break;
20654
0
      case XML_SCHEMA_TYPE_ATTRIBUTE:
20655
0
    name = (WXS_ATTR_CAST item)->name;
20656
0
    WXS_GET_GLOBAL_HASH(bucket, attrDecl)
20657
0
    break;
20658
0
      case XML_SCHEMA_TYPE_GROUP:
20659
0
    if (WXS_REDEFINED_MODEL_GROUP_DEF(item))
20660
0
        continue;
20661
0
    name = (WXS_MODEL_GROUPDEF_CAST item)->name;
20662
0
    WXS_GET_GLOBAL_HASH(bucket, groupDecl)
20663
0
    break;
20664
0
      case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
20665
0
    if (WXS_REDEFINED_ATTR_GROUP(item))
20666
0
        continue;
20667
0
    name = (WXS_ATTR_GROUP_CAST item)->name;
20668
0
    WXS_GET_GLOBAL_HASH(bucket, attrgrpDecl)
20669
0
    break;
20670
0
      case XML_SCHEMA_TYPE_IDC_KEY:
20671
0
      case XML_SCHEMA_TYPE_IDC_UNIQUE:
20672
0
      case XML_SCHEMA_TYPE_IDC_KEYREF:
20673
0
    name = (WXS_IDC_CAST item)->name;
20674
0
    WXS_GET_GLOBAL_HASH(bucket, idcDef)
20675
0
    break;
20676
0
      case XML_SCHEMA_TYPE_NOTATION:
20677
0
    name = ((xmlSchemaNotationPtr) item)->name;
20678
0
    WXS_GET_GLOBAL_HASH(bucket, notaDecl)
20679
0
    break;
20680
0
      default:
20681
0
    PERROR_INT("xmlSchemaAddComponents",
20682
0
        "Unexpected global component type");
20683
0
    continue;
20684
0
  }
20685
0
  if (*table == NULL) {
20686
0
      *table = xmlHashCreateDict(10, pctxt->dict);
20687
0
      if (*table == NULL) {
20688
0
    PERROR_INT("xmlSchemaAddComponents",
20689
0
        "failed to create a component hash table");
20690
0
    return(-1);
20691
0
      }
20692
0
  }
20693
0
  err = xmlHashAddEntry(*table, name, item);
20694
0
  if (err != 0) {
20695
0
      xmlChar *str = NULL;
20696
20697
0
      xmlSchemaCustomErr(ACTXT_CAST pctxt,
20698
0
    XML_SCHEMAP_REDEFINED_TYPE,
20699
0
    WXS_ITEM_NODE(item),
20700
0
    WXS_BASIC_CAST item,
20701
0
    "A global %s '%s' does already exist",
20702
0
    WXS_ITEM_TYPE_NAME(item),
20703
0
    xmlSchemaGetComponentQName(&str, item));
20704
0
      FREE_AND_NULL(str);
20705
0
  }
20706
0
    }
20707
    /*
20708
    * Process imported/included schemas.
20709
    */
20710
0
    if (bucket->relations != NULL) {
20711
0
  xmlSchemaSchemaRelationPtr rel = bucket->relations;
20712
0
  do {
20713
0
      if ((rel->bucket != NULL) &&
20714
0
    ((rel->bucket->flags & XML_SCHEMA_BUCKET_COMPS_ADDED) == 0)) {
20715
0
    if (xmlSchemaAddComponents(pctxt, rel->bucket) == -1)
20716
0
        return(-1);
20717
0
      }
20718
0
      rel = rel->next;
20719
0
  } while (rel != NULL);
20720
0
    }
20721
0
    return(0);
20722
0
}
20723
20724
static int
20725
xmlSchemaFixupComponents(xmlSchemaParserCtxtPtr pctxt,
20726
       xmlSchemaBucketPtr rootBucket)
20727
0
{
20728
0
    xmlSchemaConstructionCtxtPtr con = pctxt->constructor;
20729
0
    xmlSchemaTreeItemPtr item, *items;
20730
0
    int nbItems, i, ret = 0;
20731
0
    xmlSchemaBucketPtr oldbucket = con->bucket;
20732
0
    xmlSchemaElementPtr elemDecl;
20733
20734
0
#define FIXHFAILURE if (pctxt->err == XML_SCHEMAP_INTERNAL) goto exit_failure;
20735
20736
0
    if ((con->pending == NULL) ||
20737
0
  (con->pending->nbItems == 0))
20738
0
  return(0);
20739
20740
    /*
20741
    * Since xmlSchemaFixupComplexType() will create new particles
20742
    * (local components), and those particle components need a bucket
20743
    * on the constructor, we'll assure here that the constructor has
20744
    * a bucket.
20745
    * TODO: Think about storing locals _only_ on the main bucket.
20746
    */
20747
0
    if (con->bucket == NULL)
20748
0
  con->bucket = rootBucket;
20749
20750
    /* TODO:
20751
    * SPEC (src-redefine):
20752
    * (6.2) "If it has no such self-reference, then all of the
20753
    * following must be true:"
20754
20755
    * (6.2.2) The {model group} of the model group definition which
20756
    * corresponds to it per XML Representation of Model Group
20757
    * Definition Schema Components ($3.7.2) must be a `valid
20758
    * restriction` of the {model group} of that model group definition
20759
    * in I, as defined in Particle Valid (Restriction) ($3.9.6)."
20760
    */
20761
0
    xmlSchemaCheckSRCRedefineFirst(pctxt);
20762
20763
    /*
20764
    * Add global components to the schemata's hash tables.
20765
    */
20766
0
    xmlSchemaAddComponents(pctxt, rootBucket);
20767
20768
0
    pctxt->ctxtType = NULL;
20769
0
    items = (xmlSchemaTreeItemPtr *) con->pending->items;
20770
0
    nbItems = con->pending->nbItems;
20771
    /*
20772
    * Now that we have parsed *all* the schema document(s) and converted
20773
    * them to schema components, we can resolve references, apply component
20774
    * constraints, create the FSA from the content model, etc.
20775
    */
20776
    /*
20777
    * Resolve references of..
20778
    *
20779
    * 1. element declarations:
20780
    *   - the type definition
20781
    *   - the substitution group affiliation
20782
    * 2. simple/complex types:
20783
    *   - the base type definition
20784
    *   - the memberTypes of union types
20785
    *   - the itemType of list types
20786
    * 3. attributes declarations and attribute uses:
20787
    *   - the type definition
20788
    *   - if an attribute use, then the attribute declaration
20789
    * 4. attribute group references:
20790
    *   - the attribute group definition
20791
    * 5. particles:
20792
    *   - the term of the particle (e.g. a model group)
20793
    * 6. IDC key-references:
20794
    *   - the referenced IDC 'key' or 'unique' definition
20795
    * 7. Attribute prohibitions which had a "ref" attribute.
20796
    */
20797
0
    for (i = 0; i < nbItems; i++) {
20798
0
  item = items[i];
20799
0
  switch (item->type) {
20800
0
      case XML_SCHEMA_TYPE_ELEMENT:
20801
0
    xmlSchemaResolveElementReferences(
20802
0
        (xmlSchemaElementPtr) item, pctxt);
20803
0
    FIXHFAILURE;
20804
0
    break;
20805
0
      case XML_SCHEMA_TYPE_COMPLEX:
20806
0
      case XML_SCHEMA_TYPE_SIMPLE:
20807
0
    xmlSchemaResolveTypeReferences(
20808
0
        (xmlSchemaTypePtr) item, pctxt);
20809
0
    FIXHFAILURE;
20810
0
    break;
20811
0
      case XML_SCHEMA_TYPE_ATTRIBUTE:
20812
0
    xmlSchemaResolveAttrTypeReferences(
20813
0
        (xmlSchemaAttributePtr) item, pctxt);
20814
0
    FIXHFAILURE;
20815
0
    break;
20816
0
      case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
20817
0
    xmlSchemaResolveAttrUseReferences(
20818
0
        (xmlSchemaAttributeUsePtr) item, pctxt);
20819
0
    FIXHFAILURE;
20820
0
    break;
20821
0
      case XML_SCHEMA_EXTRA_QNAMEREF:
20822
0
    if ((WXS_QNAME_CAST item)->itemType ==
20823
0
        XML_SCHEMA_TYPE_ATTRIBUTEGROUP)
20824
0
    {
20825
0
        xmlSchemaResolveAttrGroupReferences(
20826
0
      WXS_QNAME_CAST item, pctxt);
20827
0
    }
20828
0
    FIXHFAILURE;
20829
0
    break;
20830
0
      case XML_SCHEMA_TYPE_SEQUENCE:
20831
0
      case XML_SCHEMA_TYPE_CHOICE:
20832
0
      case XML_SCHEMA_TYPE_ALL:
20833
0
    xmlSchemaResolveModelGroupParticleReferences(pctxt,
20834
0
        WXS_MODEL_GROUP_CAST item);
20835
0
    FIXHFAILURE;
20836
0
    break;
20837
0
      case XML_SCHEMA_TYPE_IDC_KEY:
20838
0
      case XML_SCHEMA_TYPE_IDC_UNIQUE:
20839
0
      case XML_SCHEMA_TYPE_IDC_KEYREF:
20840
0
    xmlSchemaResolveIDCKeyReferences(
20841
0
        (xmlSchemaIDCPtr) item, pctxt);
20842
0
    FIXHFAILURE;
20843
0
    break;
20844
0
      case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB:
20845
    /*
20846
    * Handle attribute prohibition which had a
20847
    * "ref" attribute.
20848
    */
20849
0
    xmlSchemaResolveAttrUseProhibReferences(
20850
0
        WXS_ATTR_PROHIB_CAST item, pctxt);
20851
0
    FIXHFAILURE;
20852
0
    break;
20853
0
      default:
20854
0
    break;
20855
0
  }
20856
0
    }
20857
0
    if (pctxt->nberrors != 0)
20858
0
  goto exit_error;
20859
20860
    /*
20861
    * Now that all references are resolved we
20862
    * can check for circularity of...
20863
    * 1. the base axis of type definitions
20864
    * 2. nested model group definitions
20865
    * 3. nested attribute group definitions
20866
    * TODO: check for circular substitution groups.
20867
    */
20868
0
    for (i = 0; i < nbItems; i++) {
20869
0
  item = items[i];
20870
  /*
20871
  * Let's better stop on the first error here.
20872
  */
20873
0
  switch (item->type) {
20874
0
      case XML_SCHEMA_TYPE_COMPLEX:
20875
0
      case XML_SCHEMA_TYPE_SIMPLE:
20876
0
    xmlSchemaCheckTypeDefCircular(
20877
0
        (xmlSchemaTypePtr) item, pctxt);
20878
0
    FIXHFAILURE;
20879
0
    if (pctxt->nberrors != 0)
20880
0
        goto exit_error;
20881
0
    break;
20882
0
      case XML_SCHEMA_TYPE_GROUP:
20883
0
    xmlSchemaCheckGroupDefCircular(
20884
0
        (xmlSchemaModelGroupDefPtr) item, pctxt);
20885
0
    FIXHFAILURE;
20886
0
    if (pctxt->nberrors != 0)
20887
0
        goto exit_error;
20888
0
    break;
20889
0
      case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
20890
0
    xmlSchemaCheckAttrGroupCircular(
20891
0
        (xmlSchemaAttributeGroupPtr) item, pctxt);
20892
0
    FIXHFAILURE;
20893
0
    if (pctxt->nberrors != 0)
20894
0
        goto exit_error;
20895
0
    break;
20896
0
      default:
20897
0
    break;
20898
0
  }
20899
0
    }
20900
0
    if (pctxt->nberrors != 0)
20901
0
  goto exit_error;
20902
    /*
20903
    * Model group definition references:
20904
    * Such a reference is reflected by a particle at the component
20905
    * level. Until now the 'term' of such particles pointed
20906
    * to the model group definition; this was done, in order to
20907
    * ease circularity checks. Now we need to set the 'term' of
20908
    * such particles to the model group of the model group definition.
20909
    */
20910
0
    for (i = 0; i < nbItems; i++) {
20911
0
  item = items[i];
20912
0
  switch (item->type) {
20913
0
      case XML_SCHEMA_TYPE_SEQUENCE:
20914
0
      case XML_SCHEMA_TYPE_CHOICE:
20915
0
    xmlSchemaModelGroupToModelGroupDefFixup(pctxt,
20916
0
        WXS_MODEL_GROUP_CAST item);
20917
0
    break;
20918
0
      default:
20919
0
    break;
20920
0
  }
20921
0
    }
20922
0
    if (pctxt->nberrors != 0)
20923
0
  goto exit_error;
20924
    /*
20925
    * Expand attribute group references of attribute group definitions.
20926
    */
20927
0
    for (i = 0; i < nbItems; i++) {
20928
0
  item = items[i];
20929
0
  switch (item->type) {
20930
0
            case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
20931
0
    if ((! WXS_ATTR_GROUP_EXPANDED(item)) &&
20932
0
        WXS_ATTR_GROUP_HAS_REFS(item))
20933
0
    {
20934
0
        xmlSchemaAttributeGroupExpandRefs(pctxt,
20935
0
      WXS_ATTR_GROUP_CAST item);
20936
0
        FIXHFAILURE;
20937
0
    }
20938
0
    break;
20939
0
      default:
20940
0
    break;
20941
0
  }
20942
0
    }
20943
0
    if (pctxt->nberrors != 0)
20944
0
  goto exit_error;
20945
    /*
20946
    * First compute the variety of simple types. This is needed as
20947
    * a separate step, since otherwise we won't be able to detect
20948
    * circular union types in all cases.
20949
    */
20950
0
    for (i = 0; i < nbItems; i++) {
20951
0
  item = items[i];
20952
0
  switch (item->type) {
20953
0
            case XML_SCHEMA_TYPE_SIMPLE:
20954
0
    if (WXS_IS_TYPE_NOT_FIXED_1((xmlSchemaTypePtr) item)) {
20955
0
        xmlSchemaFixupSimpleTypeStageOne(pctxt,
20956
0
      (xmlSchemaTypePtr) item);
20957
0
        FIXHFAILURE;
20958
0
    }
20959
0
    break;
20960
0
      default:
20961
0
    break;
20962
0
  }
20963
0
    }
20964
0
    if (pctxt->nberrors != 0)
20965
0
  goto exit_error;
20966
    /*
20967
    * Detect circular union types. Note that this needs the variety to
20968
    * be already computed.
20969
    */
20970
0
    for (i = 0; i < nbItems; i++) {
20971
0
  item = items[i];
20972
0
  switch (item->type) {
20973
0
            case XML_SCHEMA_TYPE_SIMPLE:
20974
0
    if (((xmlSchemaTypePtr) item)->memberTypes != NULL) {
20975
0
        xmlSchemaCheckUnionTypeDefCircular(pctxt,
20976
0
      (xmlSchemaTypePtr) item);
20977
0
        FIXHFAILURE;
20978
0
    }
20979
0
    break;
20980
0
      default:
20981
0
    break;
20982
0
  }
20983
0
    }
20984
0
    if (pctxt->nberrors != 0)
20985
0
  goto exit_error;
20986
20987
    /*
20988
    * Do the complete type fixup for simple types.
20989
    */
20990
0
    for (i = 0; i < nbItems; i++) {
20991
0
  item = items[i];
20992
0
  switch (item->type) {
20993
0
            case XML_SCHEMA_TYPE_SIMPLE:
20994
0
    if (WXS_IS_TYPE_NOT_FIXED(WXS_TYPE_CAST item)) {
20995
0
        xmlSchemaFixupSimpleTypeStageTwo(pctxt, WXS_TYPE_CAST item);
20996
0
        FIXHFAILURE;
20997
0
    }
20998
0
    break;
20999
0
      default:
21000
0
    break;
21001
0
  }
21002
0
    }
21003
0
    if (pctxt->nberrors != 0)
21004
0
  goto exit_error;
21005
    /*
21006
    * At this point we need build and check all simple types.
21007
    */
21008
    /*
21009
    * Apply constraints for attribute declarations.
21010
    */
21011
0
    for (i = 0; i < nbItems; i++) {
21012
0
  item = items[i];
21013
0
  switch (item->type) {
21014
0
      case XML_SCHEMA_TYPE_ATTRIBUTE:
21015
0
    xmlSchemaCheckAttrPropsCorrect(pctxt, WXS_ATTR_CAST item);
21016
0
    FIXHFAILURE;
21017
0
    break;
21018
0
      default:
21019
0
    break;
21020
0
  }
21021
0
    }
21022
0
    if (pctxt->nberrors != 0)
21023
0
  goto exit_error;
21024
    /*
21025
    * Apply constraints for attribute uses.
21026
    */
21027
0
    for (i = 0; i < nbItems; i++) {
21028
0
  item = items[i];
21029
0
  switch (item->type) {
21030
0
      case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
21031
0
    if (((xmlSchemaAttributeUsePtr)item)->defValue != NULL) {
21032
0
        xmlSchemaCheckAttrUsePropsCorrect(pctxt,
21033
0
      WXS_ATTR_USE_CAST item);
21034
0
        FIXHFAILURE;
21035
0
    }
21036
0
    break;
21037
0
      default:
21038
0
    break;
21039
0
  }
21040
0
    }
21041
0
    if (pctxt->nberrors != 0)
21042
0
  goto exit_error;
21043
21044
    /*
21045
    * Apply constraints for attribute group definitions.
21046
    */
21047
0
    for (i = 0; i < nbItems; i++) {
21048
0
  item = items[i];
21049
0
  switch (item->type) {
21050
0
  case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
21051
0
      if (( (WXS_ATTR_GROUP_CAST item)->attrUses != NULL) &&
21052
0
    ( (WXS_LIST_CAST (WXS_ATTR_GROUP_CAST item)->attrUses)->nbItems > 1))
21053
0
      {
21054
0
    xmlSchemaCheckAGPropsCorrect(pctxt, WXS_ATTR_GROUP_CAST item);
21055
0
    FIXHFAILURE;
21056
0
      }
21057
0
      break;
21058
0
  default:
21059
0
      break;
21060
0
  }
21061
0
    }
21062
0
    if (pctxt->nberrors != 0)
21063
0
  goto exit_error;
21064
21065
    /*
21066
    * Apply constraints for redefinitions.
21067
    */
21068
0
    if (WXS_CONSTRUCTOR(pctxt)->redefs != NULL)
21069
0
  xmlSchemaCheckSRCRedefineSecond(pctxt);
21070
0
    if (pctxt->nberrors != 0)
21071
0
  goto exit_error;
21072
21073
    /*
21074
    * Complex types are built and checked.
21075
    */
21076
0
    for (i = 0; i < nbItems; i++) {
21077
0
  item = con->pending->items[i];
21078
0
  switch (item->type) {
21079
0
      case XML_SCHEMA_TYPE_COMPLEX:
21080
0
    if (WXS_IS_TYPE_NOT_FIXED(WXS_TYPE_CAST item)) {
21081
0
        xmlSchemaFixupComplexType(pctxt, WXS_TYPE_CAST item);
21082
0
        FIXHFAILURE;
21083
0
    }
21084
0
    break;
21085
0
      default:
21086
0
    break;
21087
0
  }
21088
0
    }
21089
0
    if (pctxt->nberrors != 0)
21090
0
  goto exit_error;
21091
21092
    /*
21093
    * The list could have changed, since xmlSchemaFixupComplexType()
21094
    * will create particles and model groups in some cases.
21095
    */
21096
0
    items = (xmlSchemaTreeItemPtr *) con->pending->items;
21097
0
    nbItems = con->pending->nbItems;
21098
21099
    /*
21100
    * Apply some constraints for element declarations.
21101
    */
21102
0
    for (i = 0; i < nbItems; i++) {
21103
0
  item = items[i];
21104
0
  switch (item->type) {
21105
0
      case XML_SCHEMA_TYPE_ELEMENT:
21106
0
    elemDecl = (xmlSchemaElementPtr) item;
21107
21108
0
    if ((elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_CHECKED) == 0)
21109
0
    {
21110
0
        xmlSchemaCheckElementDeclComponent(
21111
0
      (xmlSchemaElementPtr) elemDecl, pctxt);
21112
0
        FIXHFAILURE;
21113
0
    }
21114
21115
#ifdef WXS_ELEM_DECL_CONS_ENABLED
21116
    /*
21117
    * Schema Component Constraint: Element Declarations Consistent
21118
    * Apply this constraint to local types of element declarations.
21119
    */
21120
    if ((WXS_ELEM_TYPEDEF(elemDecl) != NULL) &&
21121
        (WXS_IS_COMPLEX(WXS_ELEM_TYPEDEF(elemDecl))) &&
21122
        (WXS_TYPE_IS_LOCAL(WXS_ELEM_TYPEDEF(elemDecl))))
21123
    {
21124
        xmlSchemaCheckElementDeclConsistent(pctxt,
21125
      WXS_BASIC_CAST elemDecl,
21126
      WXS_TYPE_PARTICLE(WXS_ELEM_TYPEDEF(elemDecl)),
21127
      NULL, NULL, 0);
21128
    }
21129
#endif
21130
0
    break;
21131
0
      default:
21132
0
    break;
21133
0
  }
21134
0
    }
21135
0
    if (pctxt->nberrors != 0)
21136
0
  goto exit_error;
21137
21138
    /*
21139
    * Finally we can build the automaton from the content model of
21140
    * complex types.
21141
    */
21142
21143
0
    for (i = 0; i < nbItems; i++) {
21144
0
  item = items[i];
21145
0
  switch (item->type) {
21146
0
      case XML_SCHEMA_TYPE_COMPLEX:
21147
0
    xmlSchemaBuildContentModel((xmlSchemaTypePtr) item, pctxt);
21148
    /* FIXHFAILURE; */
21149
0
    break;
21150
0
      default:
21151
0
    break;
21152
0
  }
21153
0
    }
21154
0
    if (pctxt->nberrors != 0)
21155
0
  goto exit_error;
21156
    /*
21157
    * URGENT TODO: cos-element-consistent
21158
    */
21159
0
    goto exit;
21160
21161
0
exit_error:
21162
0
    ret = pctxt->err;
21163
0
    goto exit;
21164
21165
0
exit_failure:
21166
0
    ret = -1;
21167
21168
0
exit:
21169
    /*
21170
    * Reset the constructor. This is needed for XSI acquisition, since
21171
    * those items will be processed over and over again for every XSI
21172
    * if not cleared here.
21173
    */
21174
0
    con->bucket = oldbucket;
21175
0
    con->pending->nbItems = 0;
21176
0
    if (con->substGroups != NULL) {
21177
0
  xmlHashFree(con->substGroups, xmlSchemaSubstGroupFreeEntry);
21178
0
  con->substGroups = NULL;
21179
0
    }
21180
0
    if (con->redefs != NULL) {
21181
0
  xmlSchemaRedefListFree(con->redefs);
21182
0
  con->redefs = NULL;
21183
0
    }
21184
0
    return(ret);
21185
0
}
21186
/**
21187
 * xmlSchemaParse:
21188
 * @ctxt:  a schema validation context
21189
 *
21190
 * parse a schema definition resource and build an internal
21191
 * XML Schema structure which can be used to validate instances.
21192
 *
21193
 * Returns the internal XML Schema structure built from the resource or
21194
 *         NULL in case of error
21195
 */
21196
xmlSchemaPtr
21197
xmlSchemaParse(xmlSchemaParserCtxtPtr ctxt)
21198
0
{
21199
0
    xmlSchemaPtr mainSchema = NULL;
21200
0
    xmlSchemaBucketPtr bucket = NULL;
21201
0
    int res;
21202
21203
    /*
21204
    * This one is used if the schema to be parsed was specified via
21205
    * the API; i.e. not automatically by the validated instance document.
21206
    */
21207
21208
0
    if (xmlSchemaInitTypes() < 0)
21209
0
        return (NULL);
21210
21211
0
    if (ctxt == NULL)
21212
0
        return (NULL);
21213
21214
    /* TODO: Init the context. Is this all we need?*/
21215
0
    ctxt->nberrors = 0;
21216
0
    ctxt->err = 0;
21217
0
    ctxt->counter = 0;
21218
21219
    /* Create the *main* schema. */
21220
0
    mainSchema = xmlSchemaNewSchema(ctxt);
21221
0
    if (mainSchema == NULL)
21222
0
  goto exit_failure;
21223
    /*
21224
    * Create the schema constructor.
21225
    */
21226
0
    if (ctxt->constructor == NULL) {
21227
0
  ctxt->constructor = xmlSchemaConstructionCtxtCreate(ctxt->dict);
21228
0
  if (ctxt->constructor == NULL)
21229
0
      goto exit_failure;
21230
  /* Take ownership of the constructor to be able to free it. */
21231
0
  ctxt->ownsConstructor = 1;
21232
0
    }
21233
0
    ctxt->constructor->mainSchema = mainSchema;
21234
    /*
21235
    * Locate and add the schema document.
21236
    */
21237
0
    res = xmlSchemaAddSchemaDoc(ctxt, XML_SCHEMA_SCHEMA_MAIN,
21238
0
  ctxt->URL, ctxt->doc, ctxt->buffer, ctxt->size, NULL,
21239
0
  NULL, NULL, &bucket);
21240
0
    if (res == -1)
21241
0
  goto exit_failure;
21242
0
    if (res != 0)
21243
0
  goto exit;
21244
21245
0
    if (bucket == NULL) {
21246
  /* TODO: Error code, actually we failed to *locate* the schema. */
21247
0
  if (ctxt->URL)
21248
0
      xmlSchemaCustomErr(ACTXT_CAST ctxt, XML_SCHEMAP_FAILED_LOAD,
21249
0
    NULL, NULL,
21250
0
    "Failed to locate the main schema resource at '%s'",
21251
0
    ctxt->URL, NULL);
21252
0
  else
21253
0
      xmlSchemaCustomErr(ACTXT_CAST ctxt, XML_SCHEMAP_FAILED_LOAD,
21254
0
    NULL, NULL,
21255
0
    "Failed to locate the main schema resource",
21256
0
        NULL, NULL);
21257
0
  goto exit;
21258
0
    }
21259
    /* Then do the parsing for good. */
21260
0
    if (xmlSchemaParseNewDocWithContext(ctxt, mainSchema, bucket) == -1)
21261
0
  goto exit_failure;
21262
0
    if (ctxt->nberrors != 0)
21263
0
  goto exit;
21264
21265
0
    mainSchema->doc = bucket->doc;
21266
0
    mainSchema->preserve = ctxt->preserve;
21267
21268
0
    ctxt->schema = mainSchema;
21269
21270
0
    if (xmlSchemaFixupComponents(ctxt, WXS_CONSTRUCTOR(ctxt)->mainBucket) == -1)
21271
0
  goto exit_failure;
21272
21273
    /*
21274
    * TODO: This is not nice, since we cannot distinguish from the
21275
    * result if there was an internal error or not.
21276
    */
21277
0
exit:
21278
0
    if (ctxt->nberrors != 0) {
21279
0
  if (mainSchema) {
21280
0
      xmlSchemaFree(mainSchema);
21281
0
      mainSchema = NULL;
21282
0
  }
21283
0
  if (ctxt->constructor) {
21284
0
      xmlSchemaConstructionCtxtFree(ctxt->constructor);
21285
0
      ctxt->constructor = NULL;
21286
0
      ctxt->ownsConstructor = 0;
21287
0
  }
21288
0
    }
21289
0
    ctxt->schema = NULL;
21290
0
    return(mainSchema);
21291
0
exit_failure:
21292
    /*
21293
    * Quite verbose, but should catch internal errors, which were
21294
    * not communicated.
21295
    */
21296
0
    if (mainSchema) {
21297
0
        xmlSchemaFree(mainSchema);
21298
0
  mainSchema = NULL;
21299
0
    }
21300
0
    if (ctxt->constructor) {
21301
0
  xmlSchemaConstructionCtxtFree(ctxt->constructor);
21302
0
  ctxt->constructor = NULL;
21303
0
  ctxt->ownsConstructor = 0;
21304
0
    }
21305
0
    PERROR_INT2("xmlSchemaParse",
21306
0
  "An internal error occurred");
21307
0
    ctxt->schema = NULL;
21308
0
    return(NULL);
21309
0
}
21310
21311
/**
21312
 * xmlSchemaSetParserErrors:
21313
 * @ctxt:  a schema validation context
21314
 * @err:  the error callback
21315
 * @warn:  the warning callback
21316
 * @ctx:  contextual data for the callbacks
21317
 *
21318
 * DEPRECATED: Use xmlSchemaSetParserStructuredErrors.
21319
 *
21320
 * Set the callback functions used to handle errors for a validation context
21321
 */
21322
void
21323
xmlSchemaSetParserErrors(xmlSchemaParserCtxtPtr ctxt,
21324
                         xmlSchemaValidityErrorFunc err,
21325
                         xmlSchemaValidityWarningFunc warn, void *ctx)
21326
0
{
21327
0
    if (ctxt == NULL)
21328
0
        return;
21329
0
    ctxt->error = err;
21330
0
    ctxt->warning = warn;
21331
0
    ctxt->errCtxt = ctx;
21332
0
    if (ctxt->vctxt != NULL)
21333
0
  xmlSchemaSetValidErrors(ctxt->vctxt, err, warn, ctx);
21334
0
}
21335
21336
/**
21337
 * xmlSchemaSetParserStructuredErrors:
21338
 * @ctxt:  a schema parser context
21339
 * @serror:  the structured error function
21340
 * @ctx: the functions context
21341
 *
21342
 * Set the structured error callback
21343
 */
21344
void
21345
xmlSchemaSetParserStructuredErrors(xmlSchemaParserCtxtPtr ctxt,
21346
           xmlStructuredErrorFunc serror,
21347
           void *ctx)
21348
0
{
21349
0
    if (ctxt == NULL)
21350
0
  return;
21351
0
    ctxt->serror = serror;
21352
0
    ctxt->errCtxt = ctx;
21353
0
    if (ctxt->vctxt != NULL)
21354
0
  xmlSchemaSetValidStructuredErrors(ctxt->vctxt, serror, ctx);
21355
0
}
21356
21357
/**
21358
 * xmlSchemaGetParserErrors:
21359
 * @ctxt:  a XMl-Schema parser context
21360
 * @err: the error callback result
21361
 * @warn: the warning callback result
21362
 * @ctx: contextual data for the callbacks result
21363
 *
21364
 * Get the callback information used to handle errors for a parser context
21365
 *
21366
 * Returns -1 in case of failure, 0 otherwise
21367
 */
21368
int
21369
xmlSchemaGetParserErrors(xmlSchemaParserCtxtPtr ctxt,
21370
       xmlSchemaValidityErrorFunc * err,
21371
       xmlSchemaValidityWarningFunc * warn, void **ctx)
21372
0
{
21373
0
  if (ctxt == NULL)
21374
0
    return(-1);
21375
0
  if (err != NULL)
21376
0
    *err = ctxt->error;
21377
0
  if (warn != NULL)
21378
0
    *warn = ctxt->warning;
21379
0
  if (ctx != NULL)
21380
0
    *ctx = ctxt->errCtxt;
21381
0
  return(0);
21382
0
}
21383
21384
/**
21385
 * xmlSchemaSetResourceLoader:
21386
 * @ctxt:  schema parser
21387
 * @loader:  resource loader
21388
 * @data:  user data which will be passed to the loader
21389
 *
21390
 * Register a callback function that will be called to load documents
21391
 * or external entities.
21392
 *
21393
 * Available since 2.14.0.
21394
 */
21395
void
21396
xmlSchemaSetResourceLoader(xmlSchemaParserCtxtPtr ctxt,
21397
0
                           xmlResourceLoader loader, void *data) {
21398
0
    if (ctxt == NULL)
21399
0
        return;
21400
0
    ctxt->resourceLoader = loader;
21401
0
    ctxt->resourceCtxt = data;
21402
0
}
21403
21404
/**
21405
 * xmlSchemaFacetTypeToString:
21406
 * @type:  the facet type
21407
 *
21408
 * Convert the xmlSchemaTypeType to a char string.
21409
 *
21410
 * Returns the char string representation of the facet type if the
21411
 *     type is a facet and an "Internal Error" string otherwise.
21412
 */
21413
static const xmlChar *
21414
xmlSchemaFacetTypeToString(xmlSchemaTypeType type)
21415
0
{
21416
0
    switch (type) {
21417
0
        case XML_SCHEMA_FACET_PATTERN:
21418
0
            return (BAD_CAST "pattern");
21419
0
        case XML_SCHEMA_FACET_MAXEXCLUSIVE:
21420
0
            return (BAD_CAST "maxExclusive");
21421
0
        case XML_SCHEMA_FACET_MAXINCLUSIVE:
21422
0
            return (BAD_CAST "maxInclusive");
21423
0
        case XML_SCHEMA_FACET_MINEXCLUSIVE:
21424
0
            return (BAD_CAST "minExclusive");
21425
0
        case XML_SCHEMA_FACET_MININCLUSIVE:
21426
0
            return (BAD_CAST "minInclusive");
21427
0
        case XML_SCHEMA_FACET_WHITESPACE:
21428
0
            return (BAD_CAST "whiteSpace");
21429
0
        case XML_SCHEMA_FACET_ENUMERATION:
21430
0
            return (BAD_CAST "enumeration");
21431
0
        case XML_SCHEMA_FACET_LENGTH:
21432
0
            return (BAD_CAST "length");
21433
0
        case XML_SCHEMA_FACET_MAXLENGTH:
21434
0
            return (BAD_CAST "maxLength");
21435
0
        case XML_SCHEMA_FACET_MINLENGTH:
21436
0
            return (BAD_CAST "minLength");
21437
0
        case XML_SCHEMA_FACET_TOTALDIGITS:
21438
0
            return (BAD_CAST "totalDigits");
21439
0
        case XML_SCHEMA_FACET_FRACTIONDIGITS:
21440
0
            return (BAD_CAST "fractionDigits");
21441
0
        default:
21442
0
            break;
21443
0
    }
21444
0
    return (BAD_CAST "Internal Error");
21445
0
}
21446
21447
static xmlSchemaWhitespaceValueType
21448
xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type)
21449
0
{
21450
    /*
21451
    * The normalization type can be changed only for types which are derived
21452
    * from xsd:string.
21453
    */
21454
0
    if (type->type == XML_SCHEMA_TYPE_BASIC) {
21455
  /*
21456
  * Note that we assume a whitespace of preserve for anySimpleType.
21457
  */
21458
0
  if ((type->builtInType == XML_SCHEMAS_STRING) ||
21459
0
      (type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE))
21460
0
      return(XML_SCHEMA_WHITESPACE_PRESERVE);
21461
0
  else if (type->builtInType == XML_SCHEMAS_NORMSTRING)
21462
0
      return(XML_SCHEMA_WHITESPACE_REPLACE);
21463
0
  else {
21464
      /*
21465
      * For all `atomic` datatypes other than string (and types `derived`
21466
      * by `restriction` from it) the value of whiteSpace is fixed to
21467
      * collapse
21468
      * Note that this includes built-in list datatypes.
21469
      */
21470
0
      return(XML_SCHEMA_WHITESPACE_COLLAPSE);
21471
0
  }
21472
0
    } else if (WXS_IS_LIST(type)) {
21473
  /*
21474
  * For list types the facet "whiteSpace" is fixed to "collapse".
21475
  */
21476
0
  return (XML_SCHEMA_WHITESPACE_COLLAPSE);
21477
0
    } else if (WXS_IS_UNION(type)) {
21478
0
  return (XML_SCHEMA_WHITESPACE_UNKNOWN);
21479
0
    } else if (WXS_IS_ATOMIC(type)) {
21480
0
  if (type->flags & XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE)
21481
0
      return (XML_SCHEMA_WHITESPACE_PRESERVE);
21482
0
  else if (type->flags & XML_SCHEMAS_TYPE_WHITESPACE_REPLACE)
21483
0
      return (XML_SCHEMA_WHITESPACE_REPLACE);
21484
0
  else
21485
0
      return (XML_SCHEMA_WHITESPACE_COLLAPSE);
21486
0
    }
21487
0
    return (-1);
21488
0
}
21489
21490
/************************************************************************
21491
 *                  *
21492
 *      Simple type validation        *
21493
 *                  *
21494
 ************************************************************************/
21495
21496
21497
/************************************************************************
21498
 *                  *
21499
 *      DOM Validation code       *
21500
 *                  *
21501
 ************************************************************************/
21502
21503
/**
21504
 * xmlSchemaAssembleByLocation:
21505
 * @pctxt:  a schema parser context
21506
 * @vctxt:  a schema validation context
21507
 * @schema: the existing schema
21508
 * @node: the node that fired the assembling
21509
 * @nsName: the namespace name of the new schema
21510
 * @location: the location of the schema
21511
 *
21512
 * Expands an existing schema by an additional schema.
21513
 *
21514
 * Returns 0 if the new schema is correct, a positive error code
21515
 * number otherwise and -1 in case of an internal or API error.
21516
 */
21517
static int
21518
xmlSchemaAssembleByLocation(xmlSchemaValidCtxtPtr vctxt,
21519
          xmlSchemaPtr schema,
21520
          xmlNodePtr node,
21521
          const xmlChar *nsName,
21522
          const xmlChar *location)
21523
0
{
21524
0
    int ret = 0;
21525
0
    xmlSchemaParserCtxtPtr pctxt;
21526
0
    xmlSchemaBucketPtr bucket = NULL;
21527
21528
0
    if ((vctxt == NULL) || (schema == NULL))
21529
0
  return (-1);
21530
21531
0
    if (vctxt->pctxt == NULL) {
21532
0
  VERROR_INT("xmlSchemaAssembleByLocation",
21533
0
      "no parser context available");
21534
0
  return(-1);
21535
0
    }
21536
0
    pctxt = vctxt->pctxt;
21537
0
    if (pctxt->constructor == NULL) {
21538
0
  PERROR_INT("xmlSchemaAssembleByLocation",
21539
0
      "no constructor");
21540
0
  return(-1);
21541
0
    }
21542
    /*
21543
    * Acquire the schema document.
21544
    */
21545
0
    location = xmlSchemaBuildAbsoluteURI(pctxt->dict,
21546
0
  location, node);
21547
    /*
21548
    * Note that we pass XML_SCHEMA_SCHEMA_IMPORT here;
21549
    * the process will automatically change this to
21550
    * XML_SCHEMA_SCHEMA_MAIN if it is the first schema document.
21551
    */
21552
0
    ret = xmlSchemaAddSchemaDoc(pctxt, XML_SCHEMA_SCHEMA_IMPORT,
21553
0
  location, NULL, NULL, 0, node, NULL, nsName,
21554
0
  &bucket);
21555
0
    if (ret != 0)
21556
0
  return(ret);
21557
0
    if (bucket == NULL) {
21558
  /*
21559
  * Generate a warning that the document could not be located.
21560
  */
21561
0
  xmlSchemaCustomWarning(ACTXT_CAST vctxt, XML_SCHEMAV_MISC,
21562
0
      node, NULL,
21563
0
      "The document at location '%s' could not be acquired",
21564
0
      location, NULL, NULL);
21565
0
  return(ret);
21566
0
    }
21567
    /*
21568
    * The first located schema will be handled as if all other
21569
    * schemas imported by XSI were imported by this first schema.
21570
    */
21571
0
    if ((bucket != NULL) &&
21572
0
  (WXS_CONSTRUCTOR(pctxt)->bucket == NULL))
21573
0
  WXS_CONSTRUCTOR(pctxt)->bucket = bucket;
21574
    /*
21575
    * TODO: Is this handled like an import? I.e. is it not an error
21576
    * if the schema cannot be located?
21577
    */
21578
0
    if ((bucket == NULL) || (! CAN_PARSE_SCHEMA(bucket)))
21579
0
  return(0);
21580
    /*
21581
    * We will reuse the parser context for every schema imported
21582
    * directly via XSI. So reset the context.
21583
    */
21584
0
    pctxt->nberrors = 0;
21585
0
    pctxt->err = 0;
21586
0
    pctxt->doc = bucket->doc;
21587
21588
0
    ret = xmlSchemaParseNewDocWithContext(pctxt, schema, bucket);
21589
0
    if (ret == -1) {
21590
0
  pctxt->doc = NULL;
21591
0
  goto exit_failure;
21592
0
    }
21593
    /* Paranoid error channelling. */
21594
0
    if ((ret == 0) && (pctxt->nberrors != 0))
21595
0
  ret = pctxt->err;
21596
0
    if (pctxt->nberrors == 0) {
21597
  /*
21598
  * Only bother to fixup pending components, if there was
21599
  * no error yet.
21600
  * For every XSI acquired schema (and its sub-schemata) we will
21601
  * fixup the components.
21602
  */
21603
0
  xmlSchemaFixupComponents(pctxt, bucket);
21604
0
  ret = pctxt->err;
21605
  /*
21606
  * Not nice, but we need somehow to channel the schema parser
21607
  * error to the validation context.
21608
  */
21609
0
  if ((ret != 0) && (vctxt->err == 0))
21610
0
      vctxt->err = ret;
21611
0
  vctxt->nberrors += pctxt->nberrors;
21612
0
    } else {
21613
  /* Add to validation error sum. */
21614
0
  vctxt->nberrors += pctxt->nberrors;
21615
0
    }
21616
0
    pctxt->doc = NULL;
21617
0
    return(ret);
21618
0
exit_failure:
21619
0
    pctxt->doc = NULL;
21620
0
    return (-1);
21621
0
}
21622
21623
static xmlSchemaAttrInfoPtr
21624
xmlSchemaGetMetaAttrInfo(xmlSchemaValidCtxtPtr vctxt,
21625
       int metaType)
21626
0
{
21627
0
    if (vctxt->nbAttrInfos == 0)
21628
0
  return (NULL);
21629
0
    {
21630
0
  int i;
21631
0
  xmlSchemaAttrInfoPtr iattr;
21632
21633
0
  for (i = 0; i < vctxt->nbAttrInfos; i++) {
21634
0
      iattr = vctxt->attrInfos[i];
21635
0
      if (iattr->metaType == metaType)
21636
0
    return (iattr);
21637
0
  }
21638
21639
0
    }
21640
0
    return (NULL);
21641
0
}
21642
21643
/**
21644
 * xmlSchemaAssembleByXSI:
21645
 * @vctxt:  a schema validation context
21646
 *
21647
 * Expands an existing schema by an additional schema using
21648
 * the xsi:schemaLocation or xsi:noNamespaceSchemaLocation attribute
21649
 * of an instance. If xsi:noNamespaceSchemaLocation is used, @noNamespace
21650
 * must be set to 1.
21651
 *
21652
 * Returns 0 if the new schema is correct, a positive error code
21653
 * number otherwise and -1 in case of an internal or API error.
21654
 */
21655
static int
21656
xmlSchemaAssembleByXSI(xmlSchemaValidCtxtPtr vctxt)
21657
0
{
21658
0
    const xmlChar *cur, *end;
21659
0
    const xmlChar *nsname = NULL, *location;
21660
0
    int ret = 0;
21661
0
    xmlSchemaAttrInfoPtr iattr;
21662
21663
    /*
21664
    * Parse the value; we will assume an even number of values
21665
    * to be given (this is how Xerces and XSV work).
21666
    *
21667
    * URGENT TODO: !! This needs to work for both
21668
    * @noNamespaceSchemaLocation AND @schemaLocation on the same
21669
    * element !!
21670
    */
21671
0
    iattr = xmlSchemaGetMetaAttrInfo(vctxt,
21672
0
  XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC);
21673
0
    if (iattr == NULL)
21674
0
  iattr = xmlSchemaGetMetaAttrInfo(vctxt,
21675
0
  XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC);
21676
0
    if (iattr == NULL)
21677
0
  return (0);
21678
0
    cur = iattr->value;
21679
0
    do {
21680
  /*
21681
  * TODO: Move the string parsing mechanism away from here.
21682
  */
21683
0
  if (iattr->metaType == XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC) {
21684
      /*
21685
      * Get the namespace name.
21686
      */
21687
0
      while (IS_BLANK_CH(*cur))
21688
0
    cur++;
21689
0
      end = cur;
21690
0
      while ((*end != 0) && (!(IS_BLANK_CH(*end))))
21691
0
    end++;
21692
0
      if (end == cur)
21693
0
    break;
21694
      /* TODO: Don't use the schema's dict. */
21695
0
      nsname = xmlDictLookup(vctxt->schema->dict, cur, end - cur);
21696
0
      cur = end;
21697
0
  }
21698
  /*
21699
  * Get the URI.
21700
  */
21701
0
  while (IS_BLANK_CH(*cur))
21702
0
      cur++;
21703
0
  end = cur;
21704
0
  while ((*end != 0) && (!(IS_BLANK_CH(*end))))
21705
0
      end++;
21706
0
  if (end == cur) {
21707
0
      if (iattr->metaType ==
21708
0
    XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC)
21709
0
      {
21710
    /*
21711
    * If using @schemaLocation then tuples are expected.
21712
    * I.e. the namespace name *and* the document's URI.
21713
    */
21714
0
    xmlSchemaCustomWarning(ACTXT_CAST vctxt, XML_SCHEMAV_MISC,
21715
0
        iattr->node, NULL,
21716
0
        "The value must consist of tuples: the target namespace "
21717
0
        "name and the document's URI", NULL, NULL, NULL);
21718
0
      }
21719
0
      break;
21720
0
  }
21721
  /* TODO: Don't use the schema's dict. */
21722
0
  location = xmlDictLookup(vctxt->schema->dict, cur, end - cur);
21723
0
  cur = end;
21724
0
  ret = xmlSchemaAssembleByLocation(vctxt, vctxt->schema,
21725
0
      iattr->node, nsname, location);
21726
0
  if (ret == -1) {
21727
0
      VERROR_INT("xmlSchemaAssembleByXSI",
21728
0
    "assembling schemata");
21729
0
      return (-1);
21730
0
  }
21731
0
    } while (*cur != 0);
21732
0
    return (ret);
21733
0
}
21734
21735
static const xmlChar *
21736
xmlSchemaLookupNamespace(xmlSchemaValidCtxtPtr vctxt,
21737
       const xmlChar *prefix)
21738
0
{
21739
0
    if (vctxt->sax != NULL) {
21740
0
  int i, j;
21741
0
  xmlSchemaNodeInfoPtr inode;
21742
21743
0
  for (i = vctxt->depth; i >= 0; i--) {
21744
0
      if (vctxt->elemInfos[i]->nbNsBindings != 0) {
21745
0
    inode = vctxt->elemInfos[i];
21746
0
    for (j = 0; j < inode->nbNsBindings * 2; j += 2) {
21747
0
        if (((prefix == NULL) &&
21748
0
          (inode->nsBindings[j] == NULL)) ||
21749
0
      ((prefix != NULL) && xmlStrEqual(prefix,
21750
0
          inode->nsBindings[j]))) {
21751
21752
      /*
21753
      * Note that the namespace bindings are already
21754
      * in a string dict.
21755
      */
21756
0
      return (inode->nsBindings[j+1]);
21757
0
        }
21758
0
    }
21759
0
      }
21760
0
  }
21761
0
  return (NULL);
21762
0
#ifdef LIBXML_READER_ENABLED
21763
0
    } else if (vctxt->reader != NULL) {
21764
0
  xmlChar *nsName;
21765
21766
0
  nsName = xmlTextReaderLookupNamespace(vctxt->reader, prefix);
21767
0
  if (nsName != NULL) {
21768
0
      const xmlChar *ret;
21769
21770
0
      ret = xmlDictLookup(vctxt->dict, nsName, -1);
21771
0
      xmlFree(nsName);
21772
0
      return (ret);
21773
0
  } else
21774
0
      return (NULL);
21775
0
#endif
21776
0
    } else {
21777
0
  xmlNsPtr ns;
21778
21779
0
  if ((vctxt->inode->node == NULL) ||
21780
0
      (vctxt->inode->node->doc == NULL)) {
21781
0
      VERROR_INT("xmlSchemaLookupNamespace",
21782
0
    "no node or node's doc available");
21783
0
      return (NULL);
21784
0
  }
21785
0
  ns = xmlSearchNs(vctxt->inode->node->doc,
21786
0
      vctxt->inode->node, prefix);
21787
0
  if (ns != NULL)
21788
0
      return (ns->href);
21789
0
  return (NULL);
21790
0
    }
21791
0
}
21792
21793
/*
21794
* This one works on the schema of the validation context.
21795
*/
21796
static int
21797
xmlSchemaValidateNotation(xmlSchemaValidCtxtPtr vctxt,
21798
        xmlSchemaPtr schema,
21799
        xmlNodePtr node,
21800
        const xmlChar *value,
21801
        xmlSchemaValPtr *val,
21802
        int valNeeded)
21803
0
{
21804
0
    int ret;
21805
21806
0
    if (vctxt && (vctxt->schema == NULL)) {
21807
0
  VERROR_INT("xmlSchemaValidateNotation",
21808
0
      "a schema is needed on the validation context");
21809
0
  return (-1);
21810
0
    }
21811
0
    ret = xmlValidateQName(value, 1);
21812
0
    if (ret != 0)
21813
0
  return (ret);
21814
0
    {
21815
0
  xmlChar *localName = NULL;
21816
0
  xmlChar *prefix = NULL;
21817
21818
0
  localName = xmlSplitQName2(value, &prefix);
21819
0
  if (prefix != NULL) {
21820
0
      const xmlChar *nsName = NULL;
21821
21822
0
      if (vctxt != NULL)
21823
0
    nsName = xmlSchemaLookupNamespace(vctxt, BAD_CAST prefix);
21824
0
      else if (node != NULL) {
21825
0
    xmlNsPtr ns = xmlSearchNs(node->doc, node, prefix);
21826
0
    if (ns != NULL)
21827
0
        nsName = ns->href;
21828
0
      } else {
21829
0
    xmlFree(prefix);
21830
0
    xmlFree(localName);
21831
0
    return (1);
21832
0
      }
21833
0
      if (nsName == NULL) {
21834
0
    xmlFree(prefix);
21835
0
    xmlFree(localName);
21836
0
    return (1);
21837
0
      }
21838
0
      if (xmlSchemaGetNotation(schema, localName, nsName) != NULL) {
21839
0
    if ((valNeeded) && (val != NULL)) {
21840
0
        (*val) = xmlSchemaNewNOTATIONValue(xmlStrdup(localName),
21841
0
                   xmlStrdup(nsName));
21842
0
        if (*val == NULL)
21843
0
      ret = -1;
21844
0
    }
21845
0
      } else
21846
0
    ret = 1;
21847
0
      xmlFree(prefix);
21848
0
      xmlFree(localName);
21849
0
  } else {
21850
0
      if (xmlSchemaGetNotation(schema, value, NULL) != NULL) {
21851
0
    if (valNeeded && (val != NULL)) {
21852
0
        (*val) = xmlSchemaNewNOTATIONValue(
21853
0
      BAD_CAST xmlStrdup(value), NULL);
21854
0
        if (*val == NULL)
21855
0
      ret = -1;
21856
0
    }
21857
0
      } else
21858
0
    return (1);
21859
0
  }
21860
0
    }
21861
0
    return (ret);
21862
0
}
21863
21864
static int
21865
xmlSchemaVAddNodeQName(xmlSchemaValidCtxtPtr vctxt,
21866
           const xmlChar* lname,
21867
           const xmlChar* nsname)
21868
0
{
21869
0
    int i;
21870
21871
0
    lname = xmlDictLookup(vctxt->dict, lname, -1);
21872
0
    if (lname == NULL)
21873
0
  return(-1);
21874
0
    if (nsname != NULL) {
21875
0
  nsname = xmlDictLookup(vctxt->dict, nsname, -1);
21876
0
  if (nsname == NULL)
21877
0
      return(-1);
21878
0
    }
21879
0
    for (i = 0; i < vctxt->nodeQNames->nbItems; i += 2) {
21880
0
  if ((vctxt->nodeQNames->items [i] == lname) &&
21881
0
      (vctxt->nodeQNames->items[i +1] == nsname))
21882
      /* Already there */
21883
0
      return(i);
21884
0
    }
21885
    /* Add new entry. */
21886
0
    i = vctxt->nodeQNames->nbItems;
21887
0
    if (xmlSchemaItemListAdd(vctxt->nodeQNames, (void *) lname) < 0) {
21888
0
        xmlSchemaVErrMemory(vctxt);
21889
0
        return(-1);
21890
0
    }
21891
0
    if (xmlSchemaItemListAdd(vctxt->nodeQNames, (void *) nsname) < 0) {
21892
0
        vctxt->nodeQNames->nbItems--;
21893
0
        xmlSchemaVErrMemory(vctxt);
21894
0
        return(-1);
21895
0
    }
21896
0
    return(i);
21897
0
}
21898
21899
/************************************************************************
21900
 *                  *
21901
 *  Validation of identity-constraints (IDC)                            *
21902
 *                  *
21903
 ************************************************************************/
21904
21905
/**
21906
 * xmlSchemaAugmentIDC:
21907
 * @idcDef: the IDC definition
21908
 *
21909
 * Creates an augmented IDC definition item.
21910
 *
21911
 * Returns the item, or NULL on internal errors.
21912
 */
21913
static void
21914
xmlSchemaAugmentIDC(void *payload, void *data,
21915
                    const xmlChar *name ATTRIBUTE_UNUSED)
21916
0
{
21917
0
    xmlSchemaIDCPtr idcDef = (xmlSchemaIDCPtr) payload;
21918
0
    xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) data;
21919
0
    xmlSchemaIDCAugPtr aidc;
21920
21921
0
    aidc = (xmlSchemaIDCAugPtr) xmlMalloc(sizeof(xmlSchemaIDCAug));
21922
0
    if (aidc == NULL) {
21923
0
  xmlSchemaVErrMemory(vctxt);
21924
0
  return;
21925
0
    }
21926
0
    aidc->keyrefDepth = -1;
21927
0
    aidc->def = idcDef;
21928
0
    aidc->next = NULL;
21929
0
    if (vctxt->aidcs == NULL)
21930
0
  vctxt->aidcs = aidc;
21931
0
    else {
21932
0
  aidc->next = vctxt->aidcs;
21933
0
  vctxt->aidcs = aidc;
21934
0
    }
21935
    /*
21936
    * Save if we have keyrefs at all.
21937
    */
21938
0
    if ((vctxt->hasKeyrefs == 0) &&
21939
0
  (idcDef->type == XML_SCHEMA_TYPE_IDC_KEYREF))
21940
0
  vctxt->hasKeyrefs = 1;
21941
0
}
21942
21943
/**
21944
 * xmlSchemaAugmentImportedIDC:
21945
 * @imported: the imported schema
21946
 *
21947
 * Creates an augmented IDC definition for the imported schema.
21948
 */
21949
static void
21950
xmlSchemaAugmentImportedIDC(void *payload, void *data,
21951
0
                            const xmlChar *name ATTRIBUTE_UNUSED) {
21952
0
    xmlSchemaImportPtr imported = (xmlSchemaImportPtr) payload;
21953
0
    xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) data;
21954
0
    if (imported->schema->idcDef != NULL) {
21955
0
      xmlHashScan(imported->schema->idcDef, xmlSchemaAugmentIDC, vctxt);
21956
0
    }
21957
0
}
21958
21959
/**
21960
 * xmlSchemaIDCNewBinding:
21961
 * @idcDef: the IDC definition of this binding
21962
 *
21963
 * Creates a new IDC binding.
21964
 *
21965
 * Returns the new IDC binding, NULL on internal errors.
21966
 */
21967
static xmlSchemaPSVIIDCBindingPtr
21968
xmlSchemaIDCNewBinding(xmlSchemaIDCPtr idcDef)
21969
0
{
21970
0
    xmlSchemaPSVIIDCBindingPtr ret;
21971
21972
0
    ret = (xmlSchemaPSVIIDCBindingPtr) xmlMalloc(
21973
0
      sizeof(xmlSchemaPSVIIDCBinding));
21974
0
    if (ret == NULL) {
21975
0
  xmlSchemaVErrMemory(NULL);
21976
0
  return (NULL);
21977
0
    }
21978
0
    memset(ret, 0, sizeof(xmlSchemaPSVIIDCBinding));
21979
0
    ret->definition = idcDef;
21980
0
    return (ret);
21981
0
}
21982
21983
/**
21984
 * xmlSchemaIDCStoreNodeTableItem:
21985
 * @vctxt: the WXS validation context
21986
 * @item: the IDC node table item
21987
 *
21988
 * The validation context is used to store IDC node table items.
21989
 * They are stored to avoid copying them if IDC node-tables are merged
21990
 * with corresponding parent IDC node-tables (bubbling).
21991
 *
21992
 * Returns 0 if succeeded, -1 on internal errors.
21993
 */
21994
static int
21995
xmlSchemaIDCStoreNodeTableItem(xmlSchemaValidCtxtPtr vctxt,
21996
             xmlSchemaPSVIIDCNodePtr item)
21997
0
{
21998
    /*
21999
    * Add to global list.
22000
    */
22001
0
    if (vctxt->sizeIdcNodes <= vctxt->nbIdcNodes) {
22002
0
        xmlSchemaPSVIIDCNodePtr *tmp;
22003
0
        int newSize;
22004
22005
0
        newSize = xmlGrowCapacity(vctxt->sizeIdcNodes, sizeof(tmp[0]),
22006
0
                                  20, XML_MAX_ITEMS);
22007
0
  if (newSize < 0) {
22008
0
      xmlSchemaVErrMemory(vctxt);
22009
0
      return (-1);
22010
0
  }
22011
0
  tmp = xmlRealloc(vctxt->idcNodes, newSize * sizeof(tmp[0]));
22012
0
  if (tmp == NULL) {
22013
0
      xmlSchemaVErrMemory(vctxt);
22014
0
      return (-1);
22015
0
  }
22016
22017
0
        vctxt->idcNodes = tmp;
22018
0
        vctxt->sizeIdcNodes = newSize;
22019
0
    }
22020
22021
0
    vctxt->idcNodes[vctxt->nbIdcNodes++] = item;
22022
0
    return (0);
22023
0
}
22024
22025
/**
22026
 * xmlSchemaIDCStoreKey:
22027
 * @vctxt: the WXS validation context
22028
 * @item: the IDC key
22029
 *
22030
 * The validation context is used to store an IDC key.
22031
 *
22032
 * Returns 0 if succeeded, -1 on internal errors.
22033
 */
22034
static int
22035
xmlSchemaIDCStoreKey(xmlSchemaValidCtxtPtr vctxt,
22036
         xmlSchemaPSVIIDCKeyPtr key)
22037
0
{
22038
    /*
22039
    * Add to global list.
22040
    */
22041
0
    if (vctxt->sizeIdcKeys <= vctxt->nbIdcKeys) {
22042
0
        xmlSchemaPSVIIDCKeyPtr *tmp;
22043
0
        int newSize;
22044
22045
0
        newSize = xmlGrowCapacity(vctxt->sizeIdcKeys, sizeof(tmp[0]),
22046
0
                                  20, XML_MAX_ITEMS);
22047
0
  if (newSize < 0) {
22048
0
      xmlSchemaVErrMemory(vctxt);
22049
0
      return (-1);
22050
0
  }
22051
0
  tmp = xmlRealloc(vctxt->idcKeys, newSize * sizeof(tmp[0]));
22052
0
  if (tmp == NULL) {
22053
0
      xmlSchemaVErrMemory(vctxt);
22054
0
      return (-1);
22055
0
  }
22056
22057
0
        vctxt->idcKeys = tmp;
22058
0
        vctxt->sizeIdcKeys = newSize;
22059
0
    }
22060
22061
0
    vctxt->idcKeys[vctxt->nbIdcKeys++] = key;
22062
0
    return (0);
22063
0
}
22064
22065
/**
22066
 * xmlSchemaIDCAppendNodeTableItem:
22067
 * @bind: the IDC binding
22068
 * @ntItem: the node-table item
22069
 *
22070
 * Appends the IDC node-table item to the binding.
22071
 *
22072
 * Returns 0 on success and -1 on internal errors.
22073
 */
22074
static int
22075
xmlSchemaIDCAppendNodeTableItem(xmlSchemaPSVIIDCBindingPtr bind,
22076
        xmlSchemaPSVIIDCNodePtr ntItem)
22077
0
{
22078
0
    if (bind->sizeNodes <= bind->nbNodes) {
22079
0
        xmlSchemaPSVIIDCNodePtr *tmp;
22080
0
        int newSize;
22081
22082
0
        newSize = xmlGrowCapacity(bind->sizeNodes, sizeof(tmp[0]),
22083
0
                                  10, XML_MAX_ITEMS);
22084
0
  if (newSize < 0) {
22085
0
      xmlSchemaVErrMemory(NULL);
22086
0
      return(-1);
22087
0
  }
22088
0
  tmp = xmlRealloc(bind->nodeTable, newSize * sizeof(tmp[0]));
22089
0
  if (tmp == NULL) {
22090
0
      xmlSchemaVErrMemory(NULL);
22091
0
      return(-1);
22092
0
  }
22093
22094
0
        bind->nodeTable = tmp;
22095
0
        bind->sizeNodes = newSize;
22096
0
    }
22097
22098
0
    bind->nodeTable[bind->nbNodes++] = ntItem;
22099
0
    return(0);
22100
0
}
22101
22102
/**
22103
 * xmlSchemaIDCAcquireBinding:
22104
 * @vctxt: the WXS validation context
22105
 * @matcher: the IDC matcher
22106
 *
22107
 * Looks up an PSVI IDC binding, for the IDC definition and
22108
 * of the given matcher. If none found, a new one is created
22109
 * and added to the IDC table.
22110
 *
22111
 * Returns an IDC binding or NULL on internal errors.
22112
 */
22113
static xmlSchemaPSVIIDCBindingPtr
22114
xmlSchemaIDCAcquireBinding(xmlSchemaValidCtxtPtr vctxt,
22115
        xmlSchemaIDCMatcherPtr matcher)
22116
0
{
22117
0
    xmlSchemaNodeInfoPtr ielem;
22118
22119
0
    ielem = vctxt->elemInfos[matcher->depth];
22120
22121
0
    if (ielem->idcTable == NULL) {
22122
0
  ielem->idcTable = xmlSchemaIDCNewBinding(matcher->aidc->def);
22123
0
  if (ielem->idcTable == NULL)
22124
0
      return (NULL);
22125
0
  return(ielem->idcTable);
22126
0
    } else {
22127
0
  xmlSchemaPSVIIDCBindingPtr bind = NULL;
22128
22129
0
  bind = ielem->idcTable;
22130
0
  do {
22131
0
      if (bind->definition == matcher->aidc->def)
22132
0
    return(bind);
22133
0
      if (bind->next == NULL) {
22134
0
    bind->next = xmlSchemaIDCNewBinding(matcher->aidc->def);
22135
0
    if (bind->next == NULL)
22136
0
        return (NULL);
22137
0
    return(bind->next);
22138
0
      }
22139
0
      bind = bind->next;
22140
0
  } while (bind != NULL);
22141
0
    }
22142
0
    return (NULL);
22143
0
}
22144
22145
static xmlSchemaItemListPtr
22146
xmlSchemaIDCAcquireTargetList(xmlSchemaValidCtxtPtr vctxt,
22147
            xmlSchemaIDCMatcherPtr matcher)
22148
0
{
22149
0
    if (matcher->targets == NULL) {
22150
0
  matcher->targets = xmlSchemaItemListCreate();
22151
0
        if (matcher->targets == NULL)
22152
0
            xmlSchemaVErrMemory(vctxt);
22153
0
    }
22154
0
    return(matcher->targets);
22155
0
}
22156
22157
/**
22158
 * xmlSchemaIDCFreeKey:
22159
 * @key: the IDC key
22160
 *
22161
 * Frees an IDC key together with its compiled value.
22162
 */
22163
static void
22164
xmlSchemaIDCFreeKey(xmlSchemaPSVIIDCKeyPtr key)
22165
0
{
22166
0
    if (key->val != NULL)
22167
0
  xmlSchemaFreeValue(key->val);
22168
0
    xmlFree(key);
22169
0
}
22170
22171
/**
22172
 * xmlSchemaIDCFreeBinding:
22173
 *
22174
 * Frees an IDC binding. Note that the node table-items
22175
 * are not freed.
22176
 */
22177
static void
22178
xmlSchemaIDCFreeBinding(xmlSchemaPSVIIDCBindingPtr bind)
22179
0
{
22180
0
    if (bind->nodeTable != NULL)
22181
0
  xmlFree(bind->nodeTable);
22182
0
    if (bind->dupls != NULL)
22183
0
  xmlSchemaItemListFree(bind->dupls);
22184
0
    xmlFree(bind);
22185
0
}
22186
22187
/**
22188
 * xmlSchemaIDCFreeIDCTable:
22189
 * @bind: the first IDC binding in the list
22190
 *
22191
 * Frees an IDC table, i.e. all the IDC bindings in the list.
22192
 */
22193
static void
22194
xmlSchemaIDCFreeIDCTable(xmlSchemaPSVIIDCBindingPtr bind)
22195
0
{
22196
0
    xmlSchemaPSVIIDCBindingPtr prev;
22197
22198
0
    while (bind != NULL) {
22199
0
  prev = bind;
22200
0
  bind = bind->next;
22201
0
  xmlSchemaIDCFreeBinding(prev);
22202
0
    }
22203
0
}
22204
22205
static void
22206
xmlFreeIDCHashEntry (void *payload, const xmlChar *name ATTRIBUTE_UNUSED)
22207
0
{
22208
0
    xmlIDCHashEntryPtr e = payload, n;
22209
0
    while (e) {
22210
0
  n = e->next;
22211
0
  xmlFree(e);
22212
0
  e = n;
22213
0
    }
22214
0
}
22215
22216
/**
22217
 * xmlSchemaIDCFreeMatcherList:
22218
 * @matcher: the first IDC matcher in the list
22219
 *
22220
 * Frees a list of IDC matchers.
22221
 */
22222
static void
22223
xmlSchemaIDCFreeMatcherList(xmlSchemaIDCMatcherPtr matcher)
22224
0
{
22225
0
    xmlSchemaIDCMatcherPtr next;
22226
22227
0
    while (matcher != NULL) {
22228
0
  next = matcher->next;
22229
0
  if (matcher->keySeqs != NULL) {
22230
0
      int i;
22231
0
      for (i = 0; i < matcher->sizeKeySeqs; i++)
22232
0
    if (matcher->keySeqs[i] != NULL)
22233
0
        xmlFree(matcher->keySeqs[i]);
22234
0
      xmlFree(matcher->keySeqs);
22235
0
  }
22236
0
  if (matcher->targets != NULL) {
22237
0
      if (matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) {
22238
0
    int i;
22239
0
    xmlSchemaPSVIIDCNodePtr idcNode;
22240
    /*
22241
    * Node-table items for keyrefs are not stored globally
22242
    * to the validation context, since they are not bubbled.
22243
    * We need to free them here.
22244
    */
22245
0
    for (i = 0; i < matcher->targets->nbItems; i++) {
22246
0
        idcNode =
22247
0
      (xmlSchemaPSVIIDCNodePtr) matcher->targets->items[i];
22248
0
        xmlFree(idcNode->keys);
22249
0
        xmlFree(idcNode);
22250
0
    }
22251
0
      }
22252
0
      xmlSchemaItemListFree(matcher->targets);
22253
0
  }
22254
0
  if (matcher->htab != NULL)
22255
0
    xmlHashFree(matcher->htab, xmlFreeIDCHashEntry);
22256
0
  xmlFree(matcher);
22257
0
  matcher = next;
22258
0
    }
22259
0
}
22260
22261
/**
22262
 * xmlSchemaIDCReleaseMatcherList:
22263
 * @vctxt: the WXS validation context
22264
 * @matcher: the first IDC matcher in the list
22265
 *
22266
 * Caches a list of IDC matchers for reuse.
22267
 */
22268
static void
22269
xmlSchemaIDCReleaseMatcherList(xmlSchemaValidCtxtPtr vctxt,
22270
             xmlSchemaIDCMatcherPtr matcher)
22271
0
{
22272
0
    xmlSchemaIDCMatcherPtr next;
22273
22274
0
    while (matcher != NULL) {
22275
0
  next = matcher->next;
22276
0
  if (matcher->keySeqs != NULL) {
22277
0
      int i;
22278
      /*
22279
      * Don't free the array, but only the content.
22280
      */
22281
0
      for (i = 0; i < matcher->sizeKeySeqs; i++)
22282
0
    if (matcher->keySeqs[i] != NULL) {
22283
0
        xmlFree(matcher->keySeqs[i]);
22284
0
        matcher->keySeqs[i] = NULL;
22285
0
    }
22286
0
  }
22287
0
  if (matcher->targets) {
22288
0
      if (matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) {
22289
0
    int i;
22290
0
    xmlSchemaPSVIIDCNodePtr idcNode;
22291
    /*
22292
    * Node-table items for keyrefs are not stored globally
22293
    * to the validation context, since they are not bubbled.
22294
    * We need to free them here.
22295
    */
22296
0
    for (i = 0; i < matcher->targets->nbItems; i++) {
22297
0
        idcNode =
22298
0
      (xmlSchemaPSVIIDCNodePtr) matcher->targets->items[i];
22299
0
        xmlFree(idcNode->keys);
22300
0
        xmlFree(idcNode);
22301
0
    }
22302
0
      }
22303
0
      xmlSchemaItemListFree(matcher->targets);
22304
0
      matcher->targets = NULL;
22305
0
  }
22306
0
  if (matcher->htab != NULL) {
22307
0
      xmlHashFree(matcher->htab, xmlFreeIDCHashEntry);
22308
0
      matcher->htab = NULL;
22309
0
  }
22310
0
  matcher->next = NULL;
22311
  /*
22312
  * Cache the matcher.
22313
  */
22314
0
  if (vctxt->idcMatcherCache != NULL)
22315
0
      matcher->nextCached = vctxt->idcMatcherCache;
22316
0
  vctxt->idcMatcherCache = matcher;
22317
22318
0
  matcher = next;
22319
0
    }
22320
0
}
22321
22322
/**
22323
 * xmlSchemaIDCAddStateObject:
22324
 * @vctxt: the WXS validation context
22325
 * @matcher: the IDC matcher
22326
 * @sel: the XPath information
22327
 * @parent: the parent "selector" state object if any
22328
 * @type: "selector" or "field"
22329
 *
22330
 * Creates/reuses and activates state objects for the given
22331
 * XPath information; if the XPath expression consists of unions,
22332
 * multiple state objects are created for every unioned expression.
22333
 *
22334
 * Returns 0 on success and -1 on internal errors.
22335
 */
22336
static int
22337
xmlSchemaIDCAddStateObject(xmlSchemaValidCtxtPtr vctxt,
22338
      xmlSchemaIDCMatcherPtr matcher,
22339
      xmlSchemaIDCSelectPtr sel,
22340
      int type)
22341
0
{
22342
0
    xmlSchemaIDCStateObjPtr sto;
22343
22344
    /*
22345
    * Reuse the state objects from the pool.
22346
    */
22347
0
    if (vctxt->xpathStatePool != NULL) {
22348
0
  sto = vctxt->xpathStatePool;
22349
0
  vctxt->xpathStatePool = sto->next;
22350
0
  sto->next = NULL;
22351
0
    } else {
22352
  /*
22353
  * Create a new state object.
22354
  */
22355
0
  sto = (xmlSchemaIDCStateObjPtr) xmlMalloc(sizeof(xmlSchemaIDCStateObj));
22356
0
  if (sto == NULL) {
22357
0
      xmlSchemaVErrMemory(NULL);
22358
0
      return (-1);
22359
0
  }
22360
0
  memset(sto, 0, sizeof(xmlSchemaIDCStateObj));
22361
0
    }
22362
    /*
22363
    * Add to global list.
22364
    */
22365
0
    if (vctxt->xpathStates != NULL)
22366
0
  sto->next = vctxt->xpathStates;
22367
0
    vctxt->xpathStates = sto;
22368
22369
    /*
22370
    * Free the old xpath validation context.
22371
    */
22372
0
    if (sto->xpathCtxt != NULL)
22373
0
  xmlFreeStreamCtxt((xmlStreamCtxtPtr) sto->xpathCtxt);
22374
22375
    /*
22376
    * Create a new XPath (pattern) validation context.
22377
    */
22378
0
    sto->xpathCtxt = (void *) xmlPatternGetStreamCtxt(
22379
0
  (xmlPatternPtr) sel->xpathComp);
22380
0
    if (sto->xpathCtxt == NULL) {
22381
0
  VERROR_INT("xmlSchemaIDCAddStateObject",
22382
0
      "failed to create an XPath validation context");
22383
0
  return (-1);
22384
0
    }
22385
0
    sto->type = type;
22386
0
    sto->depth = vctxt->depth;
22387
0
    sto->matcher = matcher;
22388
0
    sto->sel = sel;
22389
0
    sto->nbHistory = 0;
22390
22391
0
    return (0);
22392
0
}
22393
22394
/**
22395
 * xmlSchemaXPathEvaluate:
22396
 * @vctxt: the WXS validation context
22397
 * @nodeType: the nodeType of the current node
22398
 *
22399
 * Evaluates all active XPath state objects.
22400
 *
22401
 * Returns the number of IC "field" state objects which resolved to
22402
 * this node, 0 if none resolved and -1 on internal errors.
22403
 */
22404
static int
22405
xmlSchemaXPathEvaluate(xmlSchemaValidCtxtPtr vctxt,
22406
           xmlElementType nodeType)
22407
0
{
22408
0
    xmlSchemaIDCStateObjPtr sto, head = NULL, first;
22409
0
    int res, resolved = 0, depth = vctxt->depth;
22410
22411
0
    if (vctxt->xpathStates == NULL)
22412
0
  return (0);
22413
22414
0
    if (nodeType == XML_ATTRIBUTE_NODE)
22415
0
  depth++;
22416
    /*
22417
    * Process all active XPath state objects.
22418
    */
22419
0
    first = vctxt->xpathStates;
22420
0
    sto = first;
22421
0
    while (sto != head) {
22422
0
  if (nodeType == XML_ELEMENT_NODE)
22423
0
      res = xmlStreamPush((xmlStreamCtxtPtr) sto->xpathCtxt,
22424
0
    vctxt->inode->localName, vctxt->inode->nsName);
22425
0
  else
22426
0
      res = xmlStreamPushAttr((xmlStreamCtxtPtr) sto->xpathCtxt,
22427
0
    vctxt->inode->localName, vctxt->inode->nsName);
22428
22429
0
  if (res == -1) {
22430
0
      VERROR_INT("xmlSchemaXPathEvaluate",
22431
0
    "calling xmlStreamPush()");
22432
0
      return (-1);
22433
0
  }
22434
0
  if (res == 0)
22435
0
      goto next_sto;
22436
  /*
22437
  * Full match.
22438
  */
22439
  /*
22440
  * Register a match in the state object history.
22441
  */
22442
0
        if (sto->sizeHistory <= sto->nbHistory) {
22443
0
            int *tmp;
22444
0
            int newSize;
22445
22446
0
            newSize = xmlGrowCapacity(sto->sizeHistory, sizeof(tmp[0]),
22447
0
                                      5, XML_MAX_ITEMS);
22448
0
            if (newSize < 0) {
22449
0
                xmlSchemaVErrMemory(vctxt);
22450
0
                return (-1);
22451
0
            }
22452
0
            tmp = xmlRealloc(sto->history, newSize * sizeof(tmp[0]));
22453
0
            if (tmp == NULL) {
22454
0
                xmlSchemaVErrMemory(vctxt);
22455
0
                return (-1);
22456
0
            }
22457
22458
0
            sto->history = tmp;
22459
0
            sto->sizeHistory = newSize;
22460
0
  }
22461
0
  sto->history[sto->nbHistory++] = depth;
22462
22463
0
  if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) {
22464
0
      xmlSchemaIDCSelectPtr sel;
22465
      /*
22466
      * Activate state objects for the IDC fields of
22467
      * the IDC selector.
22468
      */
22469
0
      sel = sto->matcher->aidc->def->fields;
22470
0
      while (sel != NULL) {
22471
0
    if (xmlSchemaIDCAddStateObject(vctxt, sto->matcher,
22472
0
        sel, XPATH_STATE_OBJ_TYPE_IDC_FIELD) == -1)
22473
0
        return (-1);
22474
0
    sel = sel->next;
22475
0
      }
22476
0
  } else if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_FIELD) {
22477
      /*
22478
      * An IDC key node was found by the IDC field.
22479
      */
22480
      /*
22481
      * Notify that the character value of this node is
22482
      * needed.
22483
      */
22484
0
      if (resolved == 0) {
22485
0
    if ((vctxt->inode->flags &
22486
0
        XML_SCHEMA_NODE_INFO_VALUE_NEEDED) == 0)
22487
0
    vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_VALUE_NEEDED;
22488
0
      }
22489
0
      resolved++;
22490
0
  }
22491
0
next_sto:
22492
0
  if (sto->next == NULL) {
22493
      /*
22494
      * Evaluate field state objects created on this node as well.
22495
      */
22496
0
      head = first;
22497
0
      sto = vctxt->xpathStates;
22498
0
  } else
22499
0
      sto = sto->next;
22500
0
    }
22501
0
    return (resolved);
22502
0
}
22503
22504
static const xmlChar *
22505
xmlSchemaFormatIDCKeySequence_1(xmlSchemaValidCtxtPtr vctxt,
22506
        xmlChar **buf,
22507
        xmlSchemaPSVIIDCKeyPtr *seq,
22508
        int count, int for_hash)
22509
0
{
22510
0
    int i, res;
22511
0
    xmlChar *value = NULL;
22512
22513
0
    *buf = xmlStrdup(BAD_CAST "[");
22514
0
    for (i = 0; i < count; i++) {
22515
0
  *buf = xmlStrcat(*buf, BAD_CAST "'");
22516
0
  if (!for_hash)
22517
0
      res = xmlSchemaGetCanonValueWhtspExt(seq[i]->val,
22518
0
        xmlSchemaGetWhiteSpaceFacetValue(seq[i]->type),
22519
0
        &value);
22520
0
  else {
22521
0
      res = xmlSchemaGetCanonValueHash(seq[i]->val, &value);
22522
0
  }
22523
0
  if (res == 0)
22524
0
      *buf = xmlStrcat(*buf, BAD_CAST value);
22525
0
  else {
22526
0
      VERROR_INT("xmlSchemaFormatIDCKeySequence",
22527
0
    "failed to compute a canonical value");
22528
0
      *buf = xmlStrcat(*buf, BAD_CAST "???");
22529
0
  }
22530
0
  if (i < count -1)
22531
0
      *buf = xmlStrcat(*buf, BAD_CAST "', ");
22532
0
  else
22533
0
      *buf = xmlStrcat(*buf, BAD_CAST "'");
22534
0
  if (value != NULL) {
22535
0
      xmlFree(value);
22536
0
      value = NULL;
22537
0
  }
22538
0
    }
22539
0
    *buf = xmlStrcat(*buf, BAD_CAST "]");
22540
22541
0
    return (BAD_CAST *buf);
22542
0
}
22543
22544
static const xmlChar *
22545
xmlSchemaFormatIDCKeySequence(xmlSchemaValidCtxtPtr vctxt,
22546
            xmlChar **buf,
22547
            xmlSchemaPSVIIDCKeyPtr *seq,
22548
            int count)
22549
0
{
22550
0
    return xmlSchemaFormatIDCKeySequence_1(vctxt, buf, seq, count, 0);
22551
0
}
22552
22553
static const xmlChar *
22554
xmlSchemaHashKeySequence(xmlSchemaValidCtxtPtr vctxt,
22555
       xmlChar **buf,
22556
       xmlSchemaPSVIIDCKeyPtr *seq,
22557
       int count)
22558
0
{
22559
0
    return xmlSchemaFormatIDCKeySequence_1(vctxt, buf, seq, count, 1);
22560
0
}
22561
22562
/**
22563
 * xmlSchemaXPathPop:
22564
 * @vctxt: the WXS validation context
22565
 *
22566
 * Pops all XPath states.
22567
 *
22568
 * Returns 0 on success and -1 on internal errors.
22569
 */
22570
static int
22571
xmlSchemaXPathPop(xmlSchemaValidCtxtPtr vctxt)
22572
0
{
22573
0
    xmlSchemaIDCStateObjPtr sto;
22574
0
    int res;
22575
22576
0
    if (vctxt->xpathStates == NULL)
22577
0
  return(0);
22578
0
    sto = vctxt->xpathStates;
22579
0
    do {
22580
0
  res = xmlStreamPop((xmlStreamCtxtPtr) sto->xpathCtxt);
22581
0
  if (res == -1)
22582
0
      return (-1);
22583
0
  sto = sto->next;
22584
0
    } while (sto != NULL);
22585
0
    return(0);
22586
0
}
22587
22588
/**
22589
 * xmlSchemaXPathProcessHistory:
22590
 * @vctxt: the WXS validation context
22591
 * @type: the simple/complex type of the current node if any at all
22592
 * @val: the precompiled value
22593
 *
22594
 * Processes and pops the history items of the IDC state objects.
22595
 * IDC key-sequences are validated/created on IDC bindings.
22596
 *
22597
 * Returns 0 on success and -1 on internal errors.
22598
 */
22599
static int
22600
xmlSchemaXPathProcessHistory(xmlSchemaValidCtxtPtr vctxt,
22601
           int depth)
22602
0
{
22603
0
    xmlSchemaIDCStateObjPtr sto, nextsto;
22604
0
    int res, matchDepth;
22605
0
    xmlSchemaPSVIIDCKeyPtr key = NULL;
22606
0
    xmlSchemaTypePtr type = vctxt->inode->typeDef, simpleType = NULL;
22607
22608
0
    if (vctxt->xpathStates == NULL)
22609
0
  return (0);
22610
0
    sto = vctxt->xpathStates;
22611
22612
    /*
22613
    * Evaluate the state objects.
22614
    */
22615
0
    while (sto != NULL) {
22616
0
  res = xmlStreamPop((xmlStreamCtxtPtr) sto->xpathCtxt);
22617
0
  if (res == -1) {
22618
0
      VERROR_INT("xmlSchemaXPathProcessHistory",
22619
0
    "calling xmlStreamPop()");
22620
0
      return (-1);
22621
0
  }
22622
0
  if (sto->nbHistory == 0)
22623
0
      goto deregister_check;
22624
22625
0
  matchDepth = sto->history[sto->nbHistory -1];
22626
22627
  /*
22628
  * Only matches at the current depth are of interest.
22629
  */
22630
0
  if (matchDepth != depth) {
22631
0
      sto = sto->next;
22632
0
      continue;
22633
0
  }
22634
0
  if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_FIELD) {
22635
      /*
22636
      * NOTE: According to
22637
      *   http://www.w3.org/Bugs/Public/show_bug.cgi?id=2198
22638
      *   ... the simple-content of complex types is also allowed.
22639
      */
22640
22641
0
      if (WXS_IS_COMPLEX(type)) {
22642
0
    if (WXS_HAS_SIMPLE_CONTENT(type)) {
22643
        /*
22644
        * Sanity check for complex types with simple content.
22645
        */
22646
0
        simpleType = type->contentTypeDef;
22647
0
        if (simpleType == NULL) {
22648
0
      VERROR_INT("xmlSchemaXPathProcessHistory",
22649
0
          "field resolves to a CT with simple content "
22650
0
          "but the CT is missing the ST definition");
22651
0
      return (-1);
22652
0
        }
22653
0
    } else
22654
0
        simpleType = NULL;
22655
0
      } else
22656
0
    simpleType = type;
22657
0
      if (simpleType == NULL) {
22658
0
    xmlChar *str = NULL;
22659
22660
    /*
22661
    * Not qualified if the field resolves to a node of non
22662
    * simple type.
22663
    */
22664
0
    xmlSchemaCustomErr(ACTXT_CAST vctxt,
22665
0
        XML_SCHEMAV_CVC_IDC, NULL,
22666
0
        WXS_BASIC_CAST sto->matcher->aidc->def,
22667
0
        "The XPath '%s' of a field of %s does evaluate to a node of "
22668
0
        "non-simple type",
22669
0
        sto->sel->xpath,
22670
0
        xmlSchemaGetIDCDesignation(&str, sto->matcher->aidc->def));
22671
0
    FREE_AND_NULL(str);
22672
0
    sto->nbHistory--;
22673
0
    goto deregister_check;
22674
0
      }
22675
22676
0
      if ((key == NULL) && (vctxt->inode->val == NULL)) {
22677
    /*
22678
    * Failed to provide the normalized value; maybe
22679
    * the value was invalid.
22680
    */
22681
0
    VERROR(XML_SCHEMAV_CVC_IDC,
22682
0
        WXS_BASIC_CAST sto->matcher->aidc->def,
22683
0
        "Warning: No precomputed value available, the value "
22684
0
        "was either invalid or something strange happened");
22685
0
    sto->nbHistory--;
22686
0
    goto deregister_check;
22687
0
      } else {
22688
0
    xmlSchemaIDCMatcherPtr matcher = sto->matcher;
22689
0
    xmlSchemaPSVIIDCKeyPtr *keySeq;
22690
0
    int pos, idx;
22691
22692
    /*
22693
    * The key will be anchored on the matcher's list of
22694
    * key-sequences. The position in this list is determined
22695
    * by the target node's depth relative to the matcher's
22696
    * depth of creation (i.e. the depth of the scope element).
22697
    *
22698
    * Element        Depth    Pos   List-entries
22699
    * <scope>          0              NULL
22700
    *   <bar>          1              NULL
22701
    *     <target/>    2       2      target
22702
    *   <bar>
22703
                * </scope>
22704
    *
22705
    * The size of the list is only dependent on the depth of
22706
    * the tree.
22707
    * An entry will be NULLed in selector_leave, i.e. when
22708
    * we hit the target's
22709
    */
22710
0
    pos = sto->depth - matcher->depth;
22711
0
    idx = sto->sel->index;
22712
22713
    /*
22714
    * Create/grow the array of key-sequences.
22715
    */
22716
0
                if (pos >= matcher->sizeKeySeqs) {
22717
0
                    xmlSchemaPSVIIDCKeyPtr **tmp;
22718
0
                    int oldSize = matcher->sizeKeySeqs;
22719
0
                    int newSize, i;
22720
22721
0
                    newSize = xmlGrowCapacity(pos, sizeof(tmp[0]),
22722
0
                                              10, XML_MAX_ITEMS);
22723
0
                    if (newSize < 0) {
22724
0
                        xmlSchemaVErrMemory(vctxt);
22725
0
                        return (-1);
22726
0
                    }
22727
0
                    tmp = xmlRealloc(matcher->keySeqs,
22728
0
                                     newSize * sizeof(tmp[0]));
22729
0
                    if (tmp == NULL) {
22730
0
                        xmlSchemaVErrMemory(vctxt);
22731
0
                        return (-1);
22732
0
                    }
22733
22734
0
                    matcher->keySeqs = tmp;
22735
0
                    matcher->sizeKeySeqs = newSize;
22736
22737
        /*
22738
        * The array needs to be NULLed.
22739
        * TODO: Use memset?
22740
        */
22741
0
        for (i = oldSize; i < newSize; i++)
22742
0
      matcher->keySeqs[i] = NULL;
22743
0
    }
22744
22745
    /*
22746
    * Get/create the key-sequence.
22747
    */
22748
0
    keySeq = matcher->keySeqs[pos];
22749
0
    if (keySeq == NULL) {
22750
0
        goto create_sequence;
22751
0
    } else if (keySeq[idx] != NULL) {
22752
0
        xmlChar *str = NULL;
22753
        /*
22754
        * cvc-identity-constraint:
22755
        * 3 For each node in the `target node set` all
22756
        * of the {fields}, with that node as the context
22757
        * node, evaluate to either an empty node-set or
22758
        * a node-set with exactly one member, which must
22759
        * have a simple type.
22760
        *
22761
        * The key was already set; report an error.
22762
        */
22763
0
        xmlSchemaCustomErr(ACTXT_CAST vctxt,
22764
0
      XML_SCHEMAV_CVC_IDC, NULL,
22765
0
      WXS_BASIC_CAST matcher->aidc->def,
22766
0
      "The XPath '%s' of a field of %s evaluates to a "
22767
0
      "node-set with more than one member",
22768
0
      sto->sel->xpath,
22769
0
      xmlSchemaGetIDCDesignation(&str, matcher->aidc->def));
22770
0
        FREE_AND_NULL(str);
22771
0
        sto->nbHistory--;
22772
0
        goto deregister_check;
22773
0
    } else
22774
0
        goto create_key;
22775
22776
0
create_sequence:
22777
    /*
22778
    * Create a key-sequence.
22779
    */
22780
0
    keySeq = (xmlSchemaPSVIIDCKeyPtr *) xmlMalloc(
22781
0
        matcher->aidc->def->nbFields *
22782
0
        sizeof(xmlSchemaPSVIIDCKeyPtr));
22783
0
    if (keySeq == NULL) {
22784
0
        xmlSchemaVErrMemory(NULL);
22785
0
        return(-1);
22786
0
    }
22787
0
    memset(keySeq, 0, matcher->aidc->def->nbFields *
22788
0
        sizeof(xmlSchemaPSVIIDCKeyPtr));
22789
0
    matcher->keySeqs[pos] = keySeq;
22790
0
create_key:
22791
    /*
22792
    * Create a key once per node only.
22793
    */
22794
0
    if (key == NULL) {
22795
0
        key = (xmlSchemaPSVIIDCKeyPtr) xmlMalloc(
22796
0
      sizeof(xmlSchemaPSVIIDCKey));
22797
0
        if (key == NULL) {
22798
0
      xmlSchemaVErrMemory(NULL);
22799
0
      xmlFree(keySeq);
22800
0
      matcher->keySeqs[pos] = NULL;
22801
0
      return(-1);
22802
0
        }
22803
        /*
22804
        * Consume the compiled value.
22805
        */
22806
0
        key->type = simpleType;
22807
0
        key->val = vctxt->inode->val;
22808
0
        vctxt->inode->val = NULL;
22809
        /*
22810
        * Store the key in a global list.
22811
        */
22812
0
        if (xmlSchemaIDCStoreKey(vctxt, key) == -1) {
22813
0
      xmlSchemaIDCFreeKey(key);
22814
0
      return (-1);
22815
0
        }
22816
0
    }
22817
0
    keySeq[idx] = key;
22818
0
      }
22819
0
  } else if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) {
22820
22821
0
      xmlSchemaPSVIIDCKeyPtr **keySeq = NULL;
22822
      /* xmlSchemaPSVIIDCBindingPtr bind; */
22823
0
      xmlSchemaPSVIIDCNodePtr ntItem;
22824
0
      xmlSchemaIDCMatcherPtr matcher;
22825
0
      xmlSchemaIDCPtr idc;
22826
0
      xmlSchemaItemListPtr targets;
22827
0
      int pos, i, j, nbKeys;
22828
      /*
22829
      * Here we have the following scenario:
22830
      * An IDC 'selector' state object resolved to a target node,
22831
      * during the time this target node was in the
22832
      * ancestor-or-self axis, the 'field' state object(s) looked
22833
      * out for matching nodes to create a key-sequence for this
22834
      * target node. Now we are back to this target node and need
22835
      * to put the key-sequence, together with the target node
22836
      * itself, into the node-table of the corresponding IDC
22837
      * binding.
22838
      */
22839
0
      matcher = sto->matcher;
22840
0
      idc = matcher->aidc->def;
22841
0
      nbKeys = idc->nbFields;
22842
0
      pos = depth - matcher->depth;
22843
      /*
22844
      * Check if the matcher has any key-sequences at all, plus
22845
      * if it has a key-sequence for the current target node.
22846
      */
22847
0
      if ((matcher->keySeqs == NULL) ||
22848
0
    (matcher->sizeKeySeqs <= pos)) {
22849
0
    if (idc->type == XML_SCHEMA_TYPE_IDC_KEY)
22850
0
        goto selector_key_error;
22851
0
    else
22852
0
        goto selector_leave;
22853
0
      }
22854
22855
0
      keySeq = &(matcher->keySeqs[pos]);
22856
0
      if (*keySeq == NULL) {
22857
0
    if (idc->type == XML_SCHEMA_TYPE_IDC_KEY)
22858
0
        goto selector_key_error;
22859
0
    else
22860
0
        goto selector_leave;
22861
0
      }
22862
22863
0
      for (i = 0; i < nbKeys; i++) {
22864
0
    if ((*keySeq)[i] == NULL) {
22865
        /*
22866
        * Not qualified, if not all fields did resolve.
22867
        */
22868
0
        if (idc->type == XML_SCHEMA_TYPE_IDC_KEY) {
22869
      /*
22870
      * All fields of a "key" IDC must resolve.
22871
      */
22872
0
      goto selector_key_error;
22873
0
        }
22874
0
        goto selector_leave;
22875
0
    }
22876
0
      }
22877
      /*
22878
      * All fields did resolve.
22879
      */
22880
22881
      /*
22882
      * 4.1 If the {identity-constraint category} is unique(/key),
22883
      * then no two members of the `qualified node set` have
22884
      * `key-sequences` whose members are pairwise equal, as
22885
      * defined by Equal in [XML Schemas: Datatypes].
22886
      *
22887
      * Get the IDC binding from the matcher and check for
22888
      * duplicate key-sequences.
22889
      */
22890
#if 0
22891
      bind = xmlSchemaIDCAcquireBinding(vctxt, matcher);
22892
#endif
22893
0
      targets = xmlSchemaIDCAcquireTargetList(vctxt, matcher);
22894
0
            if (targets == NULL)
22895
0
                return(-1);
22896
22897
0
      if ((idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) &&
22898
0
    (targets->nbItems != 0)) {
22899
0
    xmlSchemaPSVIIDCKeyPtr ckey, bkey, *bkeySeq;
22900
0
    xmlIDCHashEntryPtr e;
22901
22902
0
    res = 0;
22903
22904
0
    if (!matcher->htab)
22905
0
        e = NULL;
22906
0
    else {
22907
0
        xmlChar *value = NULL;
22908
0
        xmlSchemaHashKeySequence(vctxt, &value, *keySeq, nbKeys);
22909
0
        e = xmlHashLookup(matcher->htab, value);
22910
0
        FREE_AND_NULL(value);
22911
0
    }
22912
22913
    /*
22914
    * Compare the key-sequences, key by key.
22915
    */
22916
0
    for (;e; e = e->next) {
22917
0
        bkeySeq =
22918
0
      ((xmlSchemaPSVIIDCNodePtr) targets->items[e->index])->keys;
22919
0
        for (j = 0; j < nbKeys; j++) {
22920
0
      ckey = (*keySeq)[j];
22921
0
      bkey = bkeySeq[j];
22922
0
      res = xmlSchemaAreValuesEqual(ckey->val, bkey->val);
22923
0
      if (res == -1) {
22924
0
          return (-1);
22925
0
      } else if (res == 0) {
22926
          /*
22927
          * One of the keys differs, so the key-sequence
22928
          * won't be equal; get out.
22929
          */
22930
0
          break;
22931
0
      }
22932
0
        }
22933
0
        if (res == 1) {
22934
      /*
22935
      * Duplicate key-sequence found.
22936
      */
22937
0
      break;
22938
0
        }
22939
0
    }
22940
0
    if (e) {
22941
0
        xmlChar *str = NULL, *strB = NULL;
22942
        /*
22943
        * TODO: Try to report the key-sequence.
22944
        */
22945
0
        xmlSchemaCustomErr(ACTXT_CAST vctxt,
22946
0
      XML_SCHEMAV_CVC_IDC, NULL,
22947
0
      WXS_BASIC_CAST idc,
22948
0
      "Duplicate key-sequence %s in %s",
22949
0
      xmlSchemaFormatIDCKeySequence(vctxt, &str,
22950
0
          (*keySeq), nbKeys),
22951
0
      xmlSchemaGetIDCDesignation(&strB, idc));
22952
0
        FREE_AND_NULL(str);
22953
0
        FREE_AND_NULL(strB);
22954
0
        goto selector_leave;
22955
0
    }
22956
0
      }
22957
      /*
22958
      * Add a node-table item to the IDC binding.
22959
      */
22960
0
      ntItem = (xmlSchemaPSVIIDCNodePtr) xmlMalloc(
22961
0
    sizeof(xmlSchemaPSVIIDCNode));
22962
0
      if (ntItem == NULL) {
22963
0
    xmlSchemaVErrMemory(NULL);
22964
0
    xmlFree(*keySeq);
22965
0
    *keySeq = NULL;
22966
0
    return(-1);
22967
0
      }
22968
0
      memset(ntItem, 0, sizeof(xmlSchemaPSVIIDCNode));
22969
22970
      /*
22971
      * Store the node-table item in a global list.
22972
      */
22973
0
      if (idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) {
22974
0
    if (xmlSchemaIDCStoreNodeTableItem(vctxt, ntItem) == -1) {
22975
0
        xmlFree(ntItem);
22976
0
        xmlFree(*keySeq);
22977
0
        *keySeq = NULL;
22978
0
        return (-1);
22979
0
    }
22980
0
    ntItem->nodeQNameID = -1;
22981
0
      } else {
22982
    /*
22983
    * Save a cached QName for this node on the IDC node, to be
22984
    * able to report it, even if the node is not saved.
22985
    */
22986
0
    ntItem->nodeQNameID = xmlSchemaVAddNodeQName(vctxt,
22987
0
        vctxt->inode->localName, vctxt->inode->nsName);
22988
0
    if (ntItem->nodeQNameID == -1) {
22989
0
        xmlFree(ntItem);
22990
0
        xmlFree(*keySeq);
22991
0
        *keySeq = NULL;
22992
0
        return (-1);
22993
0
    }
22994
0
      }
22995
      /*
22996
      * Init the node-table item: Save the node, position and
22997
      * consume the key-sequence.
22998
      */
22999
0
      ntItem->node = vctxt->node;
23000
0
      ntItem->nodeLine = vctxt->inode->nodeLine;
23001
0
      ntItem->keys = *keySeq;
23002
0
      *keySeq = NULL;
23003
#if 0
23004
      if (xmlSchemaIDCAppendNodeTableItem(bind, ntItem) == -1)
23005
#endif
23006
0
      if (xmlSchemaItemListAdd(targets, ntItem) == -1) {
23007
0
    if (idc->type == XML_SCHEMA_TYPE_IDC_KEYREF) {
23008
        /*
23009
        * Free the item, since keyref items won't be
23010
        * put on a global list.
23011
        */
23012
0
        xmlFree(ntItem->keys);
23013
0
        xmlFree(ntItem);
23014
0
    }
23015
0
    return (-1);
23016
0
      }
23017
0
      if (idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) {
23018
0
    xmlChar *value = NULL;
23019
0
    xmlIDCHashEntryPtr r, e;
23020
0
    if (!matcher->htab)
23021
0
      matcher->htab = xmlHashCreate(4);
23022
0
    xmlSchemaHashKeySequence(vctxt, &value, ntItem->keys, nbKeys);
23023
0
    e = xmlMalloc(sizeof *e);
23024
0
                if (e == NULL) {
23025
0
                    xmlSchemaVErrMemory(vctxt);
23026
0
                    goto mem_error;
23027
0
                }
23028
0
    e->index = targets->nbItems - 1;
23029
0
    r = xmlHashLookup(matcher->htab, value);
23030
0
    if (r) {
23031
0
        e->next = r->next;
23032
0
        r->next = e;
23033
0
    } else {
23034
0
        e->next = NULL;
23035
0
        if (xmlHashAddEntry(matcher->htab, value, e) < 0) {
23036
0
                        xmlSchemaVErrMemory(vctxt);
23037
0
                        xmlFree(e);
23038
0
                    }
23039
0
    }
23040
0
mem_error:
23041
0
    FREE_AND_NULL(value);
23042
0
      }
23043
23044
0
      goto selector_leave;
23045
0
selector_key_error:
23046
0
      {
23047
0
    xmlChar *str = NULL;
23048
    /*
23049
    * 4.2.1 (KEY) The `target node set` and the
23050
    * `qualified node set` are equal, that is, every
23051
    * member of the `target node set` is also a member
23052
    * of the `qualified node set` and vice versa.
23053
    */
23054
0
    xmlSchemaCustomErr(ACTXT_CAST vctxt,
23055
0
        XML_SCHEMAV_CVC_IDC, NULL,
23056
0
        WXS_BASIC_CAST idc,
23057
0
        "Not all fields of %s evaluate to a node",
23058
0
        xmlSchemaGetIDCDesignation(&str, idc), NULL);
23059
0
    FREE_AND_NULL(str);
23060
0
      }
23061
0
selector_leave:
23062
      /*
23063
      * Free the key-sequence if not added to the IDC table.
23064
      */
23065
0
      if ((keySeq != NULL) && (*keySeq != NULL)) {
23066
0
    xmlFree(*keySeq);
23067
0
    *keySeq = NULL;
23068
0
      }
23069
0
  } /* if selector */
23070
23071
0
  sto->nbHistory--;
23072
23073
0
deregister_check:
23074
  /*
23075
  * Deregister state objects if they reach the depth of creation.
23076
  */
23077
0
  if ((sto->nbHistory == 0) && (sto->depth == depth)) {
23078
0
      if (vctxt->xpathStates != sto) {
23079
0
    VERROR_INT("xmlSchemaXPathProcessHistory",
23080
0
        "The state object to be removed is not the first "
23081
0
        "in the list");
23082
0
      }
23083
0
      nextsto = sto->next;
23084
      /*
23085
      * Unlink from the list of active XPath state objects.
23086
      */
23087
0
      vctxt->xpathStates = sto->next;
23088
0
      sto->next = vctxt->xpathStatePool;
23089
      /*
23090
      * Link it to the pool of reusable state objects.
23091
      */
23092
0
      vctxt->xpathStatePool = sto;
23093
0
      sto = nextsto;
23094
0
  } else
23095
0
      sto = sto->next;
23096
0
    } /* while (sto != NULL) */
23097
0
    return (0);
23098
0
}
23099
23100
/**
23101
 * xmlSchemaIDCRegisterMatchers:
23102
 * @vctxt: the WXS validation context
23103
 * @elemDecl: the element declaration
23104
 *
23105
 * Creates helper objects to evaluate IDC selectors/fields
23106
 * successively.
23107
 *
23108
 * Returns 0 if OK and -1 on internal errors.
23109
 */
23110
static int
23111
xmlSchemaIDCRegisterMatchers(xmlSchemaValidCtxtPtr vctxt,
23112
           xmlSchemaElementPtr elemDecl)
23113
0
{
23114
0
    xmlSchemaIDCMatcherPtr matcher, last = NULL;
23115
0
    xmlSchemaIDCPtr idc, refIdc;
23116
0
    xmlSchemaIDCAugPtr aidc;
23117
23118
0
    idc = (xmlSchemaIDCPtr) elemDecl->idcs;
23119
0
    if (idc == NULL)
23120
0
  return (0);
23121
23122
0
    if (vctxt->inode->idcMatchers != NULL) {
23123
0
  VERROR_INT("xmlSchemaIDCRegisterMatchers",
23124
0
      "The chain of IDC matchers is expected to be empty");
23125
0
  return (-1);
23126
0
    }
23127
0
    do {
23128
0
  if (idc->type == XML_SCHEMA_TYPE_IDC_KEYREF) {
23129
      /*
23130
      * Since IDCs bubbles are expensive we need to know the
23131
      * depth at which the bubbles should stop; this will be
23132
      * the depth of the top-most keyref IDC. If no keyref
23133
      * references a key/unique IDC, the keyrefDepth will
23134
      * be -1, indicating that no bubbles are needed.
23135
      */
23136
0
      refIdc = (xmlSchemaIDCPtr) idc->ref->item;
23137
0
      if (refIdc != NULL) {
23138
    /*
23139
    * Remember that we have keyrefs on this node.
23140
    */
23141
0
    vctxt->inode->hasKeyrefs = 1;
23142
    /*
23143
    * Lookup the referenced augmented IDC info.
23144
    */
23145
0
    aidc = vctxt->aidcs;
23146
0
    while (aidc != NULL) {
23147
0
        if (aidc->def == refIdc)
23148
0
      break;
23149
0
        aidc = aidc->next;
23150
0
    }
23151
0
    if (aidc == NULL) {
23152
0
        VERROR_INT("xmlSchemaIDCRegisterMatchers",
23153
0
      "Could not find an augmented IDC item for an IDC "
23154
0
      "definition");
23155
0
        return (-1);
23156
0
    }
23157
0
    if ((aidc->keyrefDepth == -1) ||
23158
0
        (vctxt->depth < aidc->keyrefDepth))
23159
0
        aidc->keyrefDepth = vctxt->depth;
23160
0
      }
23161
0
  }
23162
  /*
23163
  * Lookup the augmented IDC item for the IDC definition.
23164
  */
23165
0
  aidc = vctxt->aidcs;
23166
0
  while (aidc != NULL) {
23167
0
      if (aidc->def == idc)
23168
0
    break;
23169
0
      aidc = aidc->next;
23170
0
  }
23171
0
  if (aidc == NULL) {
23172
0
      VERROR_INT("xmlSchemaIDCRegisterMatchers",
23173
0
    "Could not find an augmented IDC item for an IDC definition");
23174
0
      return (-1);
23175
0
  }
23176
  /*
23177
  * Create an IDC matcher for every IDC definition.
23178
  */
23179
0
  if (vctxt->idcMatcherCache != NULL) {
23180
      /*
23181
      * Reuse a cached matcher.
23182
      */
23183
0
      matcher = vctxt->idcMatcherCache;
23184
0
      vctxt->idcMatcherCache = matcher->nextCached;
23185
0
      matcher->nextCached = NULL;
23186
0
  } else {
23187
0
      matcher = (xmlSchemaIDCMatcherPtr)
23188
0
    xmlMalloc(sizeof(xmlSchemaIDCMatcher));
23189
0
      if (matcher == NULL) {
23190
0
    xmlSchemaVErrMemory(vctxt);
23191
0
    return (-1);
23192
0
      }
23193
0
      memset(matcher, 0, sizeof(xmlSchemaIDCMatcher));
23194
0
  }
23195
0
  if (last == NULL)
23196
0
      vctxt->inode->idcMatchers = matcher;
23197
0
  else
23198
0
      last->next = matcher;
23199
0
  last = matcher;
23200
23201
0
  matcher->type = IDC_MATCHER;
23202
0
  matcher->depth = vctxt->depth;
23203
0
  matcher->aidc = aidc;
23204
0
  matcher->idcType = aidc->def->type;
23205
  /*
23206
  * Init the automaton state object.
23207
  */
23208
0
  if (xmlSchemaIDCAddStateObject(vctxt, matcher,
23209
0
      idc->selector, XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) == -1)
23210
0
      return (-1);
23211
23212
0
  idc = idc->next;
23213
0
    } while (idc != NULL);
23214
0
    return (0);
23215
0
}
23216
23217
static int
23218
xmlSchemaIDCFillNodeTables(xmlSchemaValidCtxtPtr vctxt,
23219
         xmlSchemaNodeInfoPtr ielem)
23220
0
{
23221
0
    xmlSchemaPSVIIDCBindingPtr bind;
23222
0
    int res, i, j, k, nbTargets, nbFields, nbDupls, nbNodeTable;
23223
0
    xmlSchemaPSVIIDCKeyPtr *keys, *ntkeys;
23224
0
    xmlSchemaPSVIIDCNodePtr *targets, *dupls;
23225
23226
0
    xmlSchemaIDCMatcherPtr matcher = ielem->idcMatchers;
23227
    /* vctxt->createIDCNodeTables */
23228
0
    while (matcher != NULL) {
23229
  /*
23230
  * Skip keyref IDCs and empty IDC target-lists.
23231
  */
23232
0
  if ((matcher->aidc->def->type == XML_SCHEMA_TYPE_IDC_KEYREF) ||
23233
0
      WXS_ILIST_IS_EMPTY(matcher->targets))
23234
0
  {
23235
0
      matcher = matcher->next;
23236
0
      continue;
23237
0
  }
23238
  /*
23239
  * If we _want_ the IDC node-table to be created in any case
23240
  * then do so. Otherwise create them only if keyrefs need them.
23241
  */
23242
0
  if ((! vctxt->createIDCNodeTables) &&
23243
0
      ((matcher->aidc->keyrefDepth == -1) ||
23244
0
       (matcher->aidc->keyrefDepth > vctxt->depth)))
23245
0
  {
23246
0
      matcher = matcher->next;
23247
0
      continue;
23248
0
  }
23249
  /*
23250
  * Get/create the IDC binding on this element for the IDC definition.
23251
  */
23252
0
  bind = xmlSchemaIDCAcquireBinding(vctxt, matcher);
23253
0
  if (bind == NULL)
23254
0
     goto internal_error;
23255
23256
0
  if (! WXS_ILIST_IS_EMPTY(bind->dupls)) {
23257
0
      dupls = (xmlSchemaPSVIIDCNodePtr *) bind->dupls->items;
23258
0
      nbDupls = bind->dupls->nbItems;
23259
0
  } else {
23260
0
      dupls = NULL;
23261
0
      nbDupls = 0;
23262
0
  }
23263
0
  if (bind->nodeTable != NULL) {
23264
0
      nbNodeTable = bind->nbNodes;
23265
0
  } else {
23266
0
      nbNodeTable = 0;
23267
0
  }
23268
23269
0
  if ((nbNodeTable == 0) && (nbDupls == 0)) {
23270
      /*
23271
      * Transfer all IDC target-nodes to the IDC node-table.
23272
      */
23273
0
            if (bind->nodeTable != NULL)
23274
0
                xmlFree(bind->nodeTable);
23275
0
      bind->nodeTable =
23276
0
    (xmlSchemaPSVIIDCNodePtr *) matcher->targets->items;
23277
0
      bind->sizeNodes = matcher->targets->sizeItems;
23278
0
      bind->nbNodes = matcher->targets->nbItems;
23279
23280
0
      matcher->targets->items = NULL;
23281
0
      matcher->targets->sizeItems = 0;
23282
0
      matcher->targets->nbItems = 0;
23283
0
      if (matcher->htab) {
23284
0
    xmlHashFree(matcher->htab, xmlFreeIDCHashEntry);
23285
0
    matcher->htab = NULL;
23286
0
      }
23287
0
  } else {
23288
      /*
23289
      * Compare the key-sequences and add to the IDC node-table.
23290
      */
23291
0
      nbTargets = matcher->targets->nbItems;
23292
0
      targets = (xmlSchemaPSVIIDCNodePtr *) matcher->targets->items;
23293
0
      nbFields = matcher->aidc->def->nbFields;
23294
0
      i = 0;
23295
0
      do {
23296
0
    keys = targets[i]->keys;
23297
0
    if (nbDupls) {
23298
        /*
23299
        * Search in already found duplicates first.
23300
        */
23301
0
        j = 0;
23302
0
        do {
23303
0
      if (nbFields == 1) {
23304
0
          res = xmlSchemaAreValuesEqual(keys[0]->val,
23305
0
        dupls[j]->keys[0]->val);
23306
0
          if (res == -1)
23307
0
        goto internal_error;
23308
0
          if (res == 1) {
23309
        /*
23310
        * Equal key-sequence.
23311
        */
23312
0
        goto next_target;
23313
0
          }
23314
0
      } else {
23315
0
          res = 0;
23316
0
          ntkeys = dupls[j]->keys;
23317
0
          for (k = 0; k < nbFields; k++) {
23318
0
        res = xmlSchemaAreValuesEqual(keys[k]->val,
23319
0
            ntkeys[k]->val);
23320
0
        if (res == -1)
23321
0
            goto internal_error;
23322
0
        if (res == 0) {
23323
            /*
23324
            * One of the keys differs.
23325
            */
23326
0
            break;
23327
0
        }
23328
0
          }
23329
0
          if (res == 1) {
23330
        /*
23331
        * Equal key-sequence found.
23332
        */
23333
0
        goto next_target;
23334
0
          }
23335
0
      }
23336
0
      j++;
23337
0
        } while (j < nbDupls);
23338
0
    }
23339
0
    if (nbNodeTable) {
23340
0
        j = 0;
23341
0
        do {
23342
0
      if (nbFields == 1) {
23343
0
          res = xmlSchemaAreValuesEqual(keys[0]->val,
23344
0
        bind->nodeTable[j]->keys[0]->val);
23345
0
          if (res == -1)
23346
0
        goto internal_error;
23347
0
          if (res == 0) {
23348
        /*
23349
        * The key-sequence differs.
23350
        */
23351
0
        goto next_node_table_entry;
23352
0
          }
23353
0
      } else {
23354
0
          res = 0;
23355
0
          ntkeys = bind->nodeTable[j]->keys;
23356
0
          for (k = 0; k < nbFields; k++) {
23357
0
        res = xmlSchemaAreValuesEqual(keys[k]->val,
23358
0
            ntkeys[k]->val);
23359
0
        if (res == -1)
23360
0
            goto internal_error;
23361
0
        if (res == 0) {
23362
            /*
23363
            * One of the keys differs.
23364
            */
23365
0
            goto next_node_table_entry;
23366
0
        }
23367
0
          }
23368
0
      }
23369
      /*
23370
      * Add the duplicate to the list of duplicates.
23371
      */
23372
0
      if (bind->dupls == NULL) {
23373
0
          bind->dupls = xmlSchemaItemListCreate();
23374
0
          if (bind->dupls == NULL)
23375
0
        goto internal_error;
23376
0
      }
23377
0
      if (xmlSchemaItemListAdd(bind->dupls, bind->nodeTable[j]) == -1)
23378
0
          goto internal_error;
23379
0
                        dupls = (xmlSchemaPSVIIDCNodePtr *) bind->dupls->items;
23380
      /*
23381
      * Remove the duplicate entry from the IDC node-table.
23382
      */
23383
0
      bind->nodeTable[j] = bind->nodeTable[bind->nbNodes -1];
23384
0
      bind->nbNodes--;
23385
23386
0
      goto next_target;
23387
23388
0
next_node_table_entry:
23389
0
      j++;
23390
0
        } while (j < nbNodeTable);
23391
0
    }
23392
    /*
23393
    * If everything is fine, then add the IDC target-node to
23394
    * the IDC node-table.
23395
    */
23396
0
    if (xmlSchemaIDCAppendNodeTableItem(bind, targets[i]) == -1)
23397
0
        goto internal_error;
23398
23399
0
next_target:
23400
0
    i++;
23401
0
      } while (i < nbTargets);
23402
0
  }
23403
0
  matcher = matcher->next;
23404
0
    }
23405
0
    return(0);
23406
23407
0
internal_error:
23408
0
    return(-1);
23409
0
}
23410
23411
/**
23412
 * xmlSchemaBubbleIDCNodeTables:
23413
 * @depth: the current tree depth
23414
 *
23415
 * Merges IDC bindings of an element at @depth into the corresponding IDC
23416
 * bindings of its parent element. If a duplicate note-table entry is found,
23417
 * both, the parent node-table entry and child entry are discarded from the
23418
 * node-table of the parent.
23419
 *
23420
 * Returns 0 if OK and -1 on internal errors.
23421
 */
23422
static int
23423
xmlSchemaBubbleIDCNodeTables(xmlSchemaValidCtxtPtr vctxt)
23424
0
{
23425
0
    xmlSchemaPSVIIDCBindingPtr bind; /* IDC bindings of the current node. */
23426
0
    xmlSchemaPSVIIDCBindingPtr *parTable, parBind = NULL; /* parent IDC bindings. */
23427
0
    xmlSchemaPSVIIDCNodePtr node, parNode = NULL, *dupls, *parNodes; /* node-table entries. */
23428
0
    xmlSchemaIDCAugPtr aidc;
23429
0
    int i, j, k, ret = 0, nbFields, oldNum, oldDupls;
23430
23431
0
    bind = vctxt->inode->idcTable;
23432
0
    if (bind == NULL) {
23433
  /* Fine, no table, no bubbles. */
23434
0
  return (0);
23435
0
    }
23436
23437
0
    parTable = &(vctxt->elemInfos[vctxt->depth -1]->idcTable);
23438
    /*
23439
    * Walk all bindings; create new or add to existing bindings.
23440
    * Remove duplicate key-sequences.
23441
    */
23442
0
    while (bind != NULL) {
23443
23444
0
  if ((bind->nbNodes == 0) && WXS_ILIST_IS_EMPTY(bind->dupls))
23445
0
      goto next_binding;
23446
  /*
23447
  * Check if the key/unique IDC table needs to be bubbled.
23448
  */
23449
0
  if (! vctxt->createIDCNodeTables) {
23450
0
      aidc = vctxt->aidcs;
23451
0
      do {
23452
0
    if (aidc->def == bind->definition) {
23453
0
        if ((aidc->keyrefDepth == -1) ||
23454
0
      (aidc->keyrefDepth >= vctxt->depth)) {
23455
0
      goto next_binding;
23456
0
        }
23457
0
        break;
23458
0
    }
23459
0
    aidc = aidc->next;
23460
0
      } while (aidc != NULL);
23461
0
  }
23462
23463
0
  if (parTable != NULL)
23464
0
      parBind = *parTable;
23465
  /*
23466
  * Search a matching parent binding for the
23467
  * IDC definition.
23468
  */
23469
0
  while (parBind != NULL) {
23470
0
      if (parBind->definition == bind->definition)
23471
0
    break;
23472
0
      parBind = parBind->next;
23473
0
  }
23474
23475
0
  if (parBind != NULL) {
23476
      /*
23477
      * Compare every node-table entry of the child node,
23478
      * i.e. the key-sequence within, ...
23479
      */
23480
0
      oldNum = parBind->nbNodes; /* Skip newly added items. */
23481
23482
0
      if (! WXS_ILIST_IS_EMPTY(parBind->dupls)) {
23483
0
    oldDupls = parBind->dupls->nbItems;
23484
0
    dupls = (xmlSchemaPSVIIDCNodePtr *) parBind->dupls->items;
23485
0
      } else {
23486
0
    dupls = NULL;
23487
0
    oldDupls = 0;
23488
0
      }
23489
23490
0
      parNodes = parBind->nodeTable;
23491
0
      nbFields = bind->definition->nbFields;
23492
23493
0
      for (i = 0; i < bind->nbNodes; i++) {
23494
0
    node = bind->nodeTable[i];
23495
0
    if (node == NULL)
23496
0
        continue;
23497
    /*
23498
    * ...with every key-sequence of the parent node, already
23499
    * evaluated to be a duplicate key-sequence.
23500
    */
23501
0
    if (oldDupls) {
23502
0
        j = 0;
23503
0
        while (j < oldDupls) {
23504
0
      if (nbFields == 1) {
23505
0
          ret = xmlSchemaAreValuesEqual(
23506
0
        node->keys[0]->val,
23507
0
        dupls[j]->keys[0]->val);
23508
0
          if (ret == -1)
23509
0
        goto internal_error;
23510
0
          if (ret == 0) {
23511
0
        j++;
23512
0
        continue;
23513
0
          }
23514
0
      } else {
23515
0
          parNode = dupls[j];
23516
0
          for (k = 0; k < nbFields; k++) {
23517
0
        ret = xmlSchemaAreValuesEqual(
23518
0
            node->keys[k]->val,
23519
0
            parNode->keys[k]->val);
23520
0
        if (ret == -1)
23521
0
            goto internal_error;
23522
0
        if (ret == 0)
23523
0
            break;
23524
0
          }
23525
0
      }
23526
0
      if (ret == 1)
23527
          /* Duplicate found. */
23528
0
          break;
23529
0
      j++;
23530
0
        }
23531
0
        if (j != oldDupls) {
23532
      /* Duplicate found. Skip this entry. */
23533
0
      continue;
23534
0
        }
23535
0
    }
23536
    /*
23537
    * ... and with every key-sequence of the parent node.
23538
    */
23539
0
    if (oldNum) {
23540
0
        j = 0;
23541
0
        while (j < oldNum) {
23542
0
      parNode = parNodes[j];
23543
0
      if (nbFields == 1) {
23544
0
          ret = xmlSchemaAreValuesEqual(
23545
0
        node->keys[0]->val,
23546
0
        parNode->keys[0]->val);
23547
0
          if (ret == -1)
23548
0
        goto internal_error;
23549
0
          if (ret == 0) {
23550
0
        j++;
23551
0
        continue;
23552
0
          }
23553
0
      } else {
23554
0
          for (k = 0; k < nbFields; k++) {
23555
0
        ret = xmlSchemaAreValuesEqual(
23556
0
            node->keys[k]->val,
23557
0
            parNode->keys[k]->val);
23558
0
        if (ret == -1)
23559
0
            goto internal_error;
23560
0
        if (ret == 0)
23561
0
            break;
23562
0
          }
23563
0
      }
23564
0
      if (ret == 1)
23565
          /* Duplicate found. */
23566
0
          break;
23567
0
      j++;
23568
0
        }
23569
0
        if (j != oldNum) {
23570
      /*
23571
      * Handle duplicates. Move the duplicate in
23572
      * the parent's node-table to the list of
23573
      * duplicates.
23574
      */
23575
0
      oldNum--;
23576
0
      parBind->nbNodes--;
23577
      /*
23578
      * Move last old item to pos of duplicate.
23579
      */
23580
0
      parNodes[j] = parNodes[oldNum];
23581
23582
0
      if (parBind->nbNodes != oldNum) {
23583
          /*
23584
          * If new items exist, move last new item to
23585
          * last of old items.
23586
          */
23587
0
          parNodes[oldNum] =
23588
0
        parNodes[parBind->nbNodes];
23589
0
      }
23590
0
      if (parBind->dupls == NULL) {
23591
0
          parBind->dupls = xmlSchemaItemListCreate();
23592
0
          if (parBind->dupls == NULL)
23593
0
        goto internal_error;
23594
0
      }
23595
0
      xmlSchemaItemListAdd(parBind->dupls, parNode);
23596
0
            dupls = (xmlSchemaPSVIIDCNodePtr *)
23597
0
                            parBind->dupls->items;
23598
0
        } else {
23599
      /*
23600
      * Add the node-table entry (node and key-sequence) of
23601
      * the child node to the node table of the parent node.
23602
      */
23603
0
                        if (parBind->nbNodes >= parBind->sizeNodes) {
23604
0
                            xmlSchemaPSVIIDCNodePtr *tmp;
23605
0
                            int newSize;
23606
23607
0
                            newSize = xmlGrowCapacity(parBind->sizeNodes,
23608
0
                                                      sizeof(tmp[0]),
23609
0
                                                      10, XML_MAX_ITEMS);
23610
0
                            if (newSize < 0) {
23611
0
                                xmlSchemaVErrMemory(vctxt);
23612
0
                                goto internal_error;
23613
0
                            }
23614
0
                            tmp = xmlRealloc(parBind->nodeTable,
23615
0
                                             newSize * sizeof(tmp[0]));
23616
0
                            if (tmp == NULL) {
23617
0
                                xmlSchemaVErrMemory(vctxt);
23618
0
                                goto internal_error;
23619
0
                            }
23620
23621
0
                            parBind->nodeTable = tmp;
23622
0
                            parBind->sizeNodes = newSize;
23623
0
      }
23624
0
      parNodes = parBind->nodeTable;
23625
      /*
23626
      * Append the new node-table entry to the 'new node-table
23627
      * entries' section.
23628
      */
23629
0
      parNodes[parBind->nbNodes++] = node;
23630
0
        }
23631
23632
0
    }
23633
23634
0
      }
23635
0
  } else {
23636
      /*
23637
      * No binding for the IDC was found: create a new one and
23638
      * copy all node-tables.
23639
      */
23640
0
      parBind = xmlSchemaIDCNewBinding(bind->definition);
23641
0
      if (parBind == NULL)
23642
0
    goto internal_error;
23643
23644
      /*
23645
      * TODO: Hmm, how to optimize the initial number of
23646
      * allocated entries?
23647
      */
23648
0
      if (bind->nbNodes != 0) {
23649
    /*
23650
    * Add all IDC node-table entries.
23651
    */
23652
0
    if (! vctxt->psviExposeIDCNodeTables) {
23653
        /*
23654
        * Just move the entries.
23655
        * NOTE: this is quite save here, since
23656
        * all the keyref lookups have already been
23657
        * performed.
23658
        */
23659
0
        parBind->nodeTable = bind->nodeTable;
23660
0
        bind->nodeTable = NULL;
23661
0
        parBind->sizeNodes = bind->sizeNodes;
23662
0
        bind->sizeNodes = 0;
23663
0
        parBind->nbNodes = bind->nbNodes;
23664
0
        bind->nbNodes = 0;
23665
0
    } else {
23666
        /*
23667
        * Copy the entries.
23668
        */
23669
0
        parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
23670
0
      xmlMalloc(bind->nbNodes *
23671
0
      sizeof(xmlSchemaPSVIIDCNodePtr));
23672
0
        if (parBind->nodeTable == NULL) {
23673
0
      xmlSchemaVErrMemory(NULL);
23674
0
      xmlSchemaIDCFreeBinding(parBind);
23675
0
      goto internal_error;
23676
0
        }
23677
0
        parBind->sizeNodes = bind->nbNodes;
23678
0
        parBind->nbNodes = bind->nbNodes;
23679
0
        memcpy(parBind->nodeTable, bind->nodeTable,
23680
0
      bind->nbNodes * sizeof(xmlSchemaPSVIIDCNodePtr));
23681
0
    }
23682
0
      }
23683
0
      if (bind->dupls) {
23684
    /*
23685
    * Move the duplicates.
23686
    */
23687
0
    if (parBind->dupls != NULL)
23688
0
        xmlSchemaItemListFree(parBind->dupls);
23689
0
    parBind->dupls = bind->dupls;
23690
0
    bind->dupls = NULL;
23691
0
      }
23692
0
            if (parTable != NULL) {
23693
0
                if (*parTable == NULL)
23694
0
                    *parTable = parBind;
23695
0
                else {
23696
0
                    parBind->next = *parTable;
23697
0
                    *parTable = parBind;
23698
0
                }
23699
0
            }
23700
0
  }
23701
23702
0
next_binding:
23703
0
  bind = bind->next;
23704
0
    }
23705
0
    return (0);
23706
23707
0
internal_error:
23708
0
    return(-1);
23709
0
}
23710
23711
/**
23712
 * xmlSchemaCheckCVCIDCKeyRef:
23713
 * @vctxt: the WXS validation context
23714
 * @elemDecl: the element declaration
23715
 *
23716
 * Check the cvc-idc-keyref constraints.
23717
 */
23718
static int
23719
xmlSchemaCheckCVCIDCKeyRef(xmlSchemaValidCtxtPtr vctxt)
23720
0
{
23721
0
    xmlSchemaIDCMatcherPtr matcher;
23722
0
    xmlSchemaPSVIIDCBindingPtr bind;
23723
23724
0
    matcher = vctxt->inode->idcMatchers;
23725
    /*
23726
    * Find a keyref.
23727
    */
23728
0
    while (matcher != NULL) {
23729
0
  if ((matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) &&
23730
0
      matcher->targets &&
23731
0
      matcher->targets->nbItems)
23732
0
  {
23733
0
      int i, j, k, res, nbFields, hasDupls;
23734
0
      xmlSchemaPSVIIDCKeyPtr *refKeys, *keys;
23735
0
      xmlSchemaPSVIIDCNodePtr refNode = NULL;
23736
0
      xmlHashTablePtr table = NULL;
23737
23738
0
      nbFields = matcher->aidc->def->nbFields;
23739
23740
      /*
23741
      * Find the IDC node-table for the referenced IDC key/unique.
23742
      */
23743
0
      bind = vctxt->inode->idcTable;
23744
0
      while (bind != NULL) {
23745
0
    if ((xmlSchemaIDCPtr) matcher->aidc->def->ref->item ==
23746
0
        bind->definition)
23747
0
        break;
23748
0
    bind = bind->next;
23749
0
      }
23750
0
      hasDupls = (bind && bind->dupls && bind->dupls->nbItems) ? 1 : 0;
23751
      /*
23752
      * Search for a matching key-sequences.
23753
      */
23754
0
      if (bind) {
23755
0
    table = xmlHashCreate(bind->nbNodes * 2);
23756
0
    for (j = 0; j < bind->nbNodes; j++) {
23757
0
        xmlChar *value;
23758
0
        xmlIDCHashEntryPtr r, e;
23759
0
        keys = bind->nodeTable[j]->keys;
23760
0
        xmlSchemaHashKeySequence(vctxt, &value, keys, nbFields);
23761
0
        e = xmlMalloc(sizeof *e);
23762
0
                    if (e == NULL) {
23763
0
                        xmlSchemaVErrMemory(vctxt);
23764
0
                        goto mem_error;
23765
0
                    }
23766
0
        e->index = j;
23767
0
        r = xmlHashLookup(table, value);
23768
0
        if (r) {
23769
0
      e->next = r->next;
23770
0
      r->next = e;
23771
0
        } else {
23772
0
      e->next = NULL;
23773
0
                        if (xmlHashAddEntry(table, value, e) < 0) {
23774
0
                            xmlSchemaVErrMemory(vctxt);
23775
0
                            xmlFree(e);
23776
0
                        }
23777
0
        }
23778
0
mem_error:
23779
0
        FREE_AND_NULL(value);
23780
0
    }
23781
0
      }
23782
0
      for (i = 0; i < matcher->targets->nbItems; i++) {
23783
0
    res = 0;
23784
0
    refNode = matcher->targets->items[i];
23785
0
    if (bind != NULL) {
23786
0
        xmlChar *value;
23787
0
        xmlIDCHashEntryPtr e;
23788
0
        refKeys = refNode->keys;
23789
0
        xmlSchemaHashKeySequence(vctxt, &value, refKeys, nbFields);
23790
0
        e = xmlHashLookup(table, value);
23791
0
        FREE_AND_NULL(value);
23792
0
        res = 0;
23793
0
        for (;e; e = e->next) {
23794
0
      keys = bind->nodeTable[e->index]->keys;
23795
0
      for (k = 0; k < nbFields; k++) {
23796
0
          res = xmlSchemaAreValuesEqual(keys[k]->val,
23797
0
                refKeys[k]->val);
23798
0
          if (res == 0)
23799
0
              break;
23800
0
          else if (res == -1) {
23801
0
        return (-1);
23802
0
          }
23803
0
      }
23804
0
      if (res == 1) {
23805
          /*
23806
           * Match found.
23807
           */
23808
0
          break;
23809
0
      }
23810
0
        }
23811
0
        if ((res == 0) && hasDupls) {
23812
      /*
23813
      * Search in duplicates
23814
      */
23815
0
      for (j = 0; j < bind->dupls->nbItems; j++) {
23816
0
          keys = ((xmlSchemaPSVIIDCNodePtr)
23817
0
        bind->dupls->items[j])->keys;
23818
0
          for (k = 0; k < nbFields; k++) {
23819
0
        res = xmlSchemaAreValuesEqual(keys[k]->val,
23820
0
            refKeys[k]->val);
23821
0
        if (res == 0)
23822
0
            break;
23823
0
        else if (res == -1) {
23824
0
            return (-1);
23825
0
        }
23826
0
          }
23827
0
          if (res == 1) {
23828
        /*
23829
        * Match in duplicates found.
23830
        */
23831
0
        xmlChar *str = NULL, *strB = NULL;
23832
0
        xmlSchemaKeyrefErr(vctxt,
23833
0
            XML_SCHEMAV_CVC_IDC, refNode,
23834
0
            (xmlSchemaTypePtr) matcher->aidc->def,
23835
0
            "More than one match found for "
23836
0
            "key-sequence %s of keyref '%s'",
23837
0
            xmlSchemaFormatIDCKeySequence(vctxt, &str,
23838
0
          refNode->keys, nbFields),
23839
0
            xmlSchemaGetComponentQName(&strB,
23840
0
          matcher->aidc->def));
23841
0
        FREE_AND_NULL(str);
23842
0
        FREE_AND_NULL(strB);
23843
0
        break;
23844
0
          }
23845
0
      }
23846
0
        }
23847
0
    }
23848
23849
0
    if (res == 0) {
23850
0
        xmlChar *str = NULL, *strB = NULL;
23851
0
        xmlSchemaKeyrefErr(vctxt,
23852
0
      XML_SCHEMAV_CVC_IDC, refNode,
23853
0
      (xmlSchemaTypePtr) matcher->aidc->def,
23854
0
      "No match found for key-sequence %s of keyref '%s'",
23855
0
      xmlSchemaFormatIDCKeySequence(vctxt, &str,
23856
0
          refNode->keys, nbFields),
23857
0
      xmlSchemaGetComponentQName(&strB, matcher->aidc->def));
23858
0
        FREE_AND_NULL(str);
23859
0
        FREE_AND_NULL(strB);
23860
0
    }
23861
0
      }
23862
0
      if (table) {
23863
0
    xmlHashFree(table, xmlFreeIDCHashEntry);
23864
0
      }
23865
0
  }
23866
0
  matcher = matcher->next;
23867
0
    }
23868
    /* TODO: Return an error if any error encountered. */
23869
0
    return (0);
23870
0
}
23871
23872
/************************************************************************
23873
 *                  *
23874
 *      XML Reader validation code                      *
23875
 *                  *
23876
 ************************************************************************/
23877
23878
static xmlSchemaAttrInfoPtr
23879
xmlSchemaGetFreshAttrInfo(xmlSchemaValidCtxtPtr vctxt)
23880
0
{
23881
0
    xmlSchemaAttrInfoPtr iattr;
23882
    /*
23883
    * Grow/create list of attribute infos.
23884
    */
23885
0
    if (vctxt->sizeAttrInfos <= vctxt->nbAttrInfos) {
23886
0
        xmlSchemaAttrInfoPtr *tmp;
23887
0
        int oldSize = vctxt->sizeAttrInfos;
23888
0
        int newSize, i;
23889
23890
0
        newSize = xmlGrowCapacity(oldSize, sizeof(tmp[0]), 5, XML_MAX_ITEMS);
23891
0
  if (newSize < 0) {
23892
0
      xmlSchemaVErrMemory(vctxt);
23893
0
      return (NULL);
23894
0
  }
23895
0
  tmp = xmlRealloc(vctxt->attrInfos, newSize * sizeof(tmp[0]));
23896
0
  if (tmp == NULL) {
23897
0
      xmlSchemaVErrMemory(vctxt);
23898
0
      return (NULL);
23899
0
  }
23900
23901
0
        vctxt->attrInfos = tmp;
23902
0
        vctxt->sizeAttrInfos = newSize;
23903
23904
0
        for (i = oldSize; i < newSize; i++)
23905
0
            vctxt->attrInfos[i] = NULL;
23906
0
    }
23907
23908
0
    iattr = vctxt->attrInfos[vctxt->nbAttrInfos];
23909
0
    if (iattr != NULL) {
23910
0
  if (iattr->localName != NULL) {
23911
0
      VERROR_INT("xmlSchemaGetFreshAttrInfo",
23912
0
    "attr info not cleared");
23913
0
      return (NULL);
23914
0
  }
23915
0
  iattr->nodeType = XML_ATTRIBUTE_NODE;
23916
0
        vctxt->nbAttrInfos++;
23917
0
  return (iattr);
23918
0
    }
23919
23920
    /*
23921
    * Create an attribute info.
23922
    */
23923
0
    iattr = (xmlSchemaAttrInfoPtr)
23924
0
  xmlMalloc(sizeof(xmlSchemaAttrInfo));
23925
0
    if (iattr == NULL) {
23926
0
  xmlSchemaVErrMemory(vctxt);
23927
0
  return (NULL);
23928
0
    }
23929
0
    memset(iattr, 0, sizeof(xmlSchemaAttrInfo));
23930
0
    iattr->nodeType = XML_ATTRIBUTE_NODE;
23931
0
    vctxt->attrInfos[vctxt->nbAttrInfos++] = iattr;
23932
23933
0
    return (iattr);
23934
0
}
23935
23936
static int
23937
xmlSchemaValidatorPushAttribute(xmlSchemaValidCtxtPtr vctxt,
23938
      xmlNodePtr attrNode,
23939
      int nodeLine,
23940
      const xmlChar *localName,
23941
      const xmlChar *nsName,
23942
      int ownedNames,
23943
      xmlChar *value,
23944
      int ownedValue)
23945
0
{
23946
0
    xmlSchemaAttrInfoPtr attr;
23947
23948
0
    attr = xmlSchemaGetFreshAttrInfo(vctxt);
23949
0
    if (attr == NULL) {
23950
0
  VERROR_INT("xmlSchemaPushAttribute",
23951
0
      "calling xmlSchemaGetFreshAttrInfo()");
23952
0
  return (-1);
23953
0
    }
23954
0
    attr->node = attrNode;
23955
0
    attr->nodeLine = nodeLine;
23956
0
    attr->state = XML_SCHEMAS_ATTR_UNKNOWN;
23957
0
    attr->localName = localName;
23958
0
    attr->nsName = nsName;
23959
0
    if (ownedNames)
23960
0
  attr->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES;
23961
    /*
23962
    * Evaluate if it's an XSI attribute.
23963
    */
23964
0
    if (nsName != NULL) {
23965
0
  if (xmlStrEqual(localName, BAD_CAST "nil")) {
23966
0
      if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
23967
0
    attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_NIL;
23968
0
      }
23969
0
  } else if (xmlStrEqual(localName, BAD_CAST "type")) {
23970
0
      if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
23971
0
    attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_TYPE;
23972
0
      }
23973
0
  } else if (xmlStrEqual(localName, BAD_CAST "schemaLocation")) {
23974
0
      if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
23975
0
    attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC;
23976
0
      }
23977
0
  } else if (xmlStrEqual(localName, BAD_CAST "noNamespaceSchemaLocation")) {
23978
0
      if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
23979
0
    attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC;
23980
0
      }
23981
0
  } else if (xmlStrEqual(attr->nsName, xmlNamespaceNs)) {
23982
0
      attr->metaType = XML_SCHEMA_ATTR_INFO_META_XMLNS;
23983
0
  }
23984
0
    }
23985
0
    attr->value = value;
23986
0
    if (ownedValue)
23987
0
  attr->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
23988
0
    if (attr->metaType != 0)
23989
0
  attr->state = XML_SCHEMAS_ATTR_META;
23990
0
    return (0);
23991
0
}
23992
23993
/**
23994
 * xmlSchemaClearElemInfo:
23995
 * @vctxt: the WXS validation context
23996
 * @ielem: the element information item
23997
 */
23998
static void
23999
xmlSchemaClearElemInfo(xmlSchemaValidCtxtPtr vctxt,
24000
           xmlSchemaNodeInfoPtr ielem)
24001
0
{
24002
0
    ielem->hasKeyrefs = 0;
24003
0
    ielem->appliedXPath = 0;
24004
0
    if (ielem->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES) {
24005
0
  FREE_AND_NULL(ielem->localName);
24006
0
  FREE_AND_NULL(ielem->nsName);
24007
0
    } else {
24008
0
  ielem->localName = NULL;
24009
0
  ielem->nsName = NULL;
24010
0
    }
24011
0
    if (ielem->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) {
24012
0
  FREE_AND_NULL(ielem->value);
24013
0
    } else {
24014
0
  ielem->value = NULL;
24015
0
    }
24016
0
    if (ielem->val != NULL) {
24017
  /*
24018
  * PSVI TODO: Be careful not to free it when the value is
24019
  * exposed via PSVI.
24020
  */
24021
0
  xmlSchemaFreeValue(ielem->val);
24022
0
  ielem->val = NULL;
24023
0
    }
24024
0
    if (ielem->idcMatchers != NULL) {
24025
  /*
24026
  * REVISIT OPTIMIZE TODO: Use a pool of IDC matchers.
24027
  *   Does it work?
24028
  */
24029
0
  xmlSchemaIDCReleaseMatcherList(vctxt, ielem->idcMatchers);
24030
#if 0
24031
  xmlSchemaIDCFreeMatcherList(ielem->idcMatchers);
24032
#endif
24033
0
  ielem->idcMatchers = NULL;
24034
0
    }
24035
0
    if (ielem->idcTable != NULL) {
24036
  /*
24037
  * OPTIMIZE TODO: Use a pool of IDC tables??.
24038
  */
24039
0
  xmlSchemaIDCFreeIDCTable(ielem->idcTable);
24040
0
  ielem->idcTable = NULL;
24041
0
    }
24042
0
    if (ielem->regexCtxt != NULL) {
24043
0
  xmlRegFreeExecCtxt(ielem->regexCtxt);
24044
0
  ielem->regexCtxt = NULL;
24045
0
    }
24046
0
    if (ielem->nsBindings != NULL) {
24047
0
  xmlFree((xmlChar **)ielem->nsBindings);
24048
0
  ielem->nsBindings = NULL;
24049
0
  ielem->nbNsBindings = 0;
24050
0
  ielem->sizeNsBindings = 0;
24051
0
    }
24052
0
}
24053
24054
/**
24055
 * xmlSchemaGetFreshElemInfo:
24056
 * @vctxt: the schema validation context
24057
 *
24058
 * Creates/reuses and initializes the element info item for
24059
 * the current tree depth.
24060
 *
24061
 * Returns the element info item or NULL on API or internal errors.
24062
 */
24063
static xmlSchemaNodeInfoPtr
24064
xmlSchemaGetFreshElemInfo(xmlSchemaValidCtxtPtr vctxt)
24065
0
{
24066
0
    xmlSchemaNodeInfoPtr info = NULL;
24067
24068
0
    if (vctxt->depth > vctxt->sizeElemInfos) {
24069
0
  VERROR_INT("xmlSchemaGetFreshElemInfo",
24070
0
      "inconsistent depth encountered");
24071
0
  return (NULL);
24072
0
    }
24073
0
    if (vctxt->sizeElemInfos <= vctxt->depth) {
24074
0
        xmlSchemaNodeInfoPtr *tmp;
24075
0
        int oldSize = vctxt->sizeElemInfos;
24076
0
        int newSize, i;
24077
24078
0
        newSize = xmlGrowCapacity(oldSize, sizeof(tmp[0]), 10, XML_MAX_ITEMS);
24079
0
        if (newSize < 0) {
24080
0
            xmlSchemaVErrMemory(vctxt);
24081
0
            return (NULL);
24082
0
        }
24083
0
        tmp = xmlRealloc(vctxt->elemInfos, newSize * sizeof(tmp[0]));
24084
0
        if (tmp == NULL) {
24085
0
            xmlSchemaVErrMemory(vctxt);
24086
0
            return (NULL);
24087
0
        }
24088
24089
0
        vctxt->elemInfos = tmp;
24090
0
        vctxt->sizeElemInfos = newSize;
24091
24092
  /*
24093
  * We need the new memory to be NULLed.
24094
  * TODO: Use memset instead?
24095
  */
24096
0
  for (i = oldSize; i < newSize; i++)
24097
0
      vctxt->elemInfos[i] = NULL;
24098
0
    } else
24099
0
  info = vctxt->elemInfos[vctxt->depth];
24100
24101
0
    if (info == NULL) {
24102
0
  info = (xmlSchemaNodeInfoPtr)
24103
0
      xmlMalloc(sizeof(xmlSchemaNodeInfo));
24104
0
  if (info == NULL) {
24105
0
      xmlSchemaVErrMemory(vctxt);
24106
0
      return (NULL);
24107
0
  }
24108
0
  vctxt->elemInfos[vctxt->depth] = info;
24109
0
    } else {
24110
0
  if (info->localName != NULL) {
24111
0
      VERROR_INT("xmlSchemaGetFreshElemInfo",
24112
0
    "elem info has not been cleared");
24113
0
      return (NULL);
24114
0
  }
24115
0
    }
24116
0
    memset(info, 0, sizeof(xmlSchemaNodeInfo));
24117
0
    info->nodeType = XML_ELEMENT_NODE;
24118
0
    info->depth = vctxt->depth;
24119
24120
0
    return (info);
24121
0
}
24122
24123
0
#define ACTIVATE_ATTRIBUTE(item) vctxt->inode = (xmlSchemaNodeInfoPtr) item;
24124
0
#define ACTIVATE_ELEM vctxt->inode = vctxt->elemInfos[vctxt->depth];
24125
0
#define ACTIVATE_PARENT_ELEM vctxt->inode = vctxt->elemInfos[vctxt->depth -1];
24126
24127
static int
24128
xmlSchemaValidateFacets(xmlSchemaAbstractCtxtPtr actxt,
24129
      xmlNodePtr node,
24130
      xmlSchemaTypePtr type,
24131
      xmlSchemaValType valType,
24132
      const xmlChar * value,
24133
      xmlSchemaValPtr val,
24134
      unsigned long length,
24135
      int fireErrors)
24136
0
{
24137
0
    int ret, error = 0, found;
24138
24139
0
    xmlSchemaTypePtr tmpType;
24140
0
    xmlSchemaFacetLinkPtr facetLink;
24141
0
    xmlSchemaFacetPtr facet;
24142
0
    unsigned long len = 0;
24143
0
    xmlSchemaWhitespaceValueType ws;
24144
24145
    /*
24146
    * In Libxml2, derived built-in types have currently no explicit facets.
24147
    */
24148
0
    if (type->type == XML_SCHEMA_TYPE_BASIC)
24149
0
  return (0);
24150
24151
    /*
24152
    * NOTE: Do not jump away, if the facetSet of the given type is
24153
    * empty: until now, "pattern" and "enumeration" facets of the
24154
    * *base types* need to be checked as well.
24155
    */
24156
0
    if (type->facetSet == NULL)
24157
0
  goto pattern_and_enum;
24158
24159
0
    if (! WXS_IS_ATOMIC(type)) {
24160
0
  if (WXS_IS_LIST(type))
24161
0
      goto WXS_IS_LIST;
24162
0
  else
24163
0
      goto pattern_and_enum;
24164
0
    }
24165
24166
    /*
24167
    * Whitespace handling is only of importance for string-based
24168
    * types.
24169
    */
24170
0
    tmpType = xmlSchemaGetPrimitiveType(type);
24171
0
    if ((tmpType->builtInType == XML_SCHEMAS_STRING) ||
24172
0
  WXS_IS_ANY_SIMPLE_TYPE(tmpType)) {
24173
0
  ws = xmlSchemaGetWhiteSpaceFacetValue(type);
24174
0
    } else
24175
0
  ws = XML_SCHEMA_WHITESPACE_COLLAPSE;
24176
24177
    /*
24178
    * If the value was not computed (for string or
24179
    * anySimpleType based types), then use the provided
24180
    * type.
24181
    */
24182
0
    if (val != NULL)
24183
0
  valType = xmlSchemaGetValType(val);
24184
24185
0
    ret = 0;
24186
0
    for (facetLink = type->facetSet; facetLink != NULL;
24187
0
  facetLink = facetLink->next) {
24188
  /*
24189
  * Skip the pattern "whiteSpace": it is used to
24190
  * format the character content beforehand.
24191
  */
24192
0
  switch (facetLink->facet->type) {
24193
0
      case XML_SCHEMA_FACET_WHITESPACE:
24194
0
      case XML_SCHEMA_FACET_PATTERN:
24195
0
      case XML_SCHEMA_FACET_ENUMERATION:
24196
0
    continue;
24197
0
      case XML_SCHEMA_FACET_LENGTH:
24198
0
      case XML_SCHEMA_FACET_MINLENGTH:
24199
0
      case XML_SCHEMA_FACET_MAXLENGTH:
24200
0
    ret = xmlSchemaValidateLengthFacetWhtsp(facetLink->facet,
24201
0
        valType, value, val, &len, ws);
24202
0
    break;
24203
0
      default:
24204
0
    ret = xmlSchemaValidateFacetWhtsp(facetLink->facet, ws,
24205
0
        valType, value, val, ws);
24206
0
    break;
24207
0
  }
24208
0
  if (ret < 0) {
24209
0
      AERROR_INT("xmlSchemaValidateFacets",
24210
0
    "validating against a atomic type facet");
24211
0
      return (-1);
24212
0
  } else if (ret > 0) {
24213
0
      if (fireErrors)
24214
0
    xmlSchemaFacetErr(actxt, ret, node,
24215
0
    value, len, type, facetLink->facet, NULL, NULL, NULL);
24216
0
      else
24217
0
    return (ret);
24218
0
      if (error == 0)
24219
0
    error = ret;
24220
0
  }
24221
0
  ret = 0;
24222
0
    }
24223
24224
0
WXS_IS_LIST:
24225
0
    if (! WXS_IS_LIST(type))
24226
0
  goto pattern_and_enum;
24227
    /*
24228
    * "length", "minLength" and "maxLength" of list types.
24229
    */
24230
0
    ret = 0;
24231
0
    for (facetLink = type->facetSet; facetLink != NULL;
24232
0
  facetLink = facetLink->next) {
24233
24234
0
  switch (facetLink->facet->type) {
24235
0
      case XML_SCHEMA_FACET_LENGTH:
24236
0
      case XML_SCHEMA_FACET_MINLENGTH:
24237
0
      case XML_SCHEMA_FACET_MAXLENGTH:
24238
0
    ret = xmlSchemaValidateListSimpleTypeFacet(facetLink->facet,
24239
0
        value, length, NULL);
24240
0
    break;
24241
0
      default:
24242
0
    continue;
24243
0
  }
24244
0
  if (ret < 0) {
24245
0
      AERROR_INT("xmlSchemaValidateFacets",
24246
0
    "validating against a list type facet");
24247
0
      return (-1);
24248
0
  } else if (ret > 0) {
24249
0
      if (fireErrors)
24250
0
    xmlSchemaFacetErr(actxt, ret, node,
24251
0
    value, length, type, facetLink->facet, NULL, NULL, NULL);
24252
0
      else
24253
0
    return (ret);
24254
0
      if (error == 0)
24255
0
    error = ret;
24256
0
  }
24257
0
  ret = 0;
24258
0
    }
24259
24260
0
pattern_and_enum:
24261
0
    found = 0;
24262
    /*
24263
    * Process enumerations. Facet values are in the value space
24264
    * of the defining type's base type. This seems to be a bug in the
24265
    * XML Schema 1.0 spec. Use the whitespace type of the base type.
24266
    * Only the first set of enumerations in the ancestor-or-self axis
24267
    * is used for validation.
24268
    */
24269
0
    ret = 0;
24270
0
    tmpType = type;
24271
0
    do {
24272
0
        for (facet = tmpType->facets; facet != NULL; facet = facet->next) {
24273
0
            if (facet->type != XML_SCHEMA_FACET_ENUMERATION)
24274
0
                continue;
24275
0
            found = 1;
24276
0
            ret = xmlSchemaAreValuesEqual(facet->val, val);
24277
0
            if (ret == 1)
24278
0
                break;
24279
0
            else if (ret < 0) {
24280
0
                AERROR_INT("xmlSchemaValidateFacets",
24281
0
                    "validating against an enumeration facet");
24282
0
                return (-1);
24283
0
            }
24284
0
        }
24285
0
        if (ret != 0)
24286
0
            break;
24287
        /*
24288
        * Break on the first set of enumerations. Any additional
24289
        *  enumerations which might be existent on the ancestors
24290
        *  of the current type are restricted by this set; thus
24291
        *  *must* *not* be taken into account.
24292
        */
24293
0
        if (found)
24294
0
            break;
24295
0
        tmpType = tmpType->baseType;
24296
0
    } while ((tmpType != NULL) &&
24297
0
        (tmpType->type != XML_SCHEMA_TYPE_BASIC));
24298
0
    if (found && (ret == 0)) {
24299
0
        ret = XML_SCHEMAV_CVC_ENUMERATION_VALID;
24300
0
        if (fireErrors) {
24301
0
            xmlSchemaFacetErr(actxt, ret, node,
24302
0
                value, 0, type, NULL, NULL, NULL, NULL);
24303
0
        } else
24304
0
            return (ret);
24305
0
        if (error == 0)
24306
0
            error = ret;
24307
0
    }
24308
24309
    /*
24310
    * Process patters. Pattern facets are ORed at type level
24311
    * and ANDed if derived. Walk the base type axis.
24312
    */
24313
0
    tmpType = type;
24314
0
    facet = NULL;
24315
0
    do {
24316
0
        found = 0;
24317
0
        for (facetLink = tmpType->facetSet; facetLink != NULL;
24318
0
            facetLink = facetLink->next) {
24319
0
            if (facetLink->facet->type != XML_SCHEMA_FACET_PATTERN)
24320
0
                continue;
24321
0
            found = 1;
24322
            /*
24323
            * NOTE that for patterns, @value needs to be the
24324
            * normalized value.
24325
            */
24326
0
            ret = xmlRegexpExec(facetLink->facet->regexp, value);
24327
0
            if (ret == 1)
24328
0
                break;
24329
0
            else if (ret < 0) {
24330
0
                AERROR_INT("xmlSchemaValidateFacets",
24331
0
                    "validating against a pattern facet");
24332
0
                return (-1);
24333
0
            } else {
24334
                /*
24335
                * Save the last non-validating facet.
24336
                */
24337
0
                facet = facetLink->facet;
24338
0
            }
24339
0
        }
24340
0
        if (found && (ret != 1)) {
24341
0
            ret = XML_SCHEMAV_CVC_PATTERN_VALID;
24342
0
            if (fireErrors) {
24343
0
                xmlSchemaFacetErr(actxt, ret, node,
24344
0
                    value, 0, type, facet, NULL, NULL, NULL);
24345
0
            } else
24346
0
                return (ret);
24347
0
            if (error == 0)
24348
0
                error = ret;
24349
0
            break;
24350
0
        }
24351
0
        tmpType = tmpType->baseType;
24352
0
    } while ((tmpType != NULL) && (tmpType->type != XML_SCHEMA_TYPE_BASIC));
24353
24354
0
    return (error);
24355
0
}
24356
24357
static xmlChar *
24358
xmlSchemaNormalizeValue(xmlSchemaTypePtr type,
24359
      const xmlChar *value)
24360
0
{
24361
0
    switch (xmlSchemaGetWhiteSpaceFacetValue(type)) {
24362
0
  case XML_SCHEMA_WHITESPACE_COLLAPSE:
24363
0
      return (xmlSchemaCollapseString(value));
24364
0
  case XML_SCHEMA_WHITESPACE_REPLACE:
24365
0
      return (xmlSchemaWhiteSpaceReplace(value));
24366
0
  default:
24367
0
      return (NULL);
24368
0
    }
24369
0
}
24370
24371
static int
24372
xmlSchemaValidateQName(xmlSchemaValidCtxtPtr vctxt,
24373
           const xmlChar *value,
24374
           xmlSchemaValPtr *val,
24375
           int valNeeded)
24376
0
{
24377
0
    int ret;
24378
0
    xmlChar *stripped;
24379
0
    const xmlChar *nsName;
24380
0
    xmlChar *local, *prefix = NULL;
24381
24382
0
    ret = xmlValidateQName(value, 1);
24383
0
    if (ret != 0) {
24384
0
  if (ret == -1) {
24385
0
      VERROR_INT("xmlSchemaValidateQName",
24386
0
    "calling xmlValidateQName()");
24387
0
      return (-1);
24388
0
  }
24389
0
  return( XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1);
24390
0
    }
24391
    /*
24392
    * NOTE: xmlSplitQName2 will always return a duplicated
24393
    * strings.
24394
    */
24395
    /* TODO: Export and use xmlSchemaStrip instead */
24396
0
    stripped = xmlSchemaCollapseString(value);
24397
0
    local = xmlSplitQName2(stripped ? stripped : value, &prefix);
24398
0
    xmlFree(stripped);
24399
0
    if (local == NULL)
24400
0
  local = xmlStrdup(value);
24401
    /*
24402
    * OPTIMIZE TODO: Use flags for:
24403
    *  - is there any namespace binding?
24404
    *  - is there a default namespace?
24405
    */
24406
0
    nsName = xmlSchemaLookupNamespace(vctxt, prefix);
24407
24408
0
    if (prefix != NULL) {
24409
0
  xmlFree(prefix);
24410
  /*
24411
  * A namespace must be found if the prefix is
24412
  * NOT NULL.
24413
  */
24414
0
  if (nsName == NULL) {
24415
0
      ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
24416
0
      xmlSchemaCustomErr(ACTXT_CAST vctxt, ret, NULL,
24417
0
    WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
24418
0
    "The QName value '%s' has no "
24419
0
    "corresponding namespace declaration in "
24420
0
    "scope", value, NULL);
24421
0
      if (local != NULL)
24422
0
    xmlFree(local);
24423
0
      return (ret);
24424
0
  }
24425
0
    }
24426
0
    if (valNeeded && val) {
24427
0
  if (nsName != NULL)
24428
0
      *val = xmlSchemaNewQNameValue(
24429
0
    BAD_CAST xmlStrdup(nsName), BAD_CAST local);
24430
0
  else
24431
0
      *val = xmlSchemaNewQNameValue(NULL,
24432
0
    BAD_CAST local);
24433
0
    } else
24434
0
  xmlFree(local);
24435
0
    return (0);
24436
0
}
24437
24438
/*
24439
* cvc-simple-type
24440
*/
24441
static int
24442
xmlSchemaVCheckCVCSimpleType(xmlSchemaAbstractCtxtPtr actxt,
24443
           xmlNodePtr node,
24444
           xmlSchemaTypePtr type,
24445
           const xmlChar *value,
24446
           xmlSchemaValPtr *retVal,
24447
           int fireErrors,
24448
           int normalize,
24449
           int isNormalized)
24450
0
{
24451
0
    int ret = 0, valNeeded = (retVal) ? 1 : 0;
24452
0
    xmlSchemaValPtr val = NULL;
24453
    /* xmlSchemaWhitespaceValueType ws; */
24454
0
    xmlChar *normValue = NULL;
24455
24456
0
#define NORMALIZE(atype) \
24457
0
    if ((! isNormalized) && \
24458
0
    (normalize || (type->flags & XML_SCHEMAS_TYPE_NORMVALUENEEDED))) { \
24459
0
  normValue = xmlSchemaNormalizeValue(atype, value); \
24460
0
  if (normValue != NULL) \
24461
0
      value = normValue; \
24462
0
  isNormalized = 1; \
24463
0
    }
24464
24465
0
    if ((retVal != NULL) && (*retVal != NULL)) {
24466
0
  xmlSchemaFreeValue(*retVal);
24467
0
  *retVal = NULL;
24468
0
    }
24469
    /*
24470
    * 3.14.4 Simple Type Definition Validation Rules
24471
    * Validation Rule: String Valid
24472
    */
24473
    /*
24474
    * 1 It is schema-valid with respect to that definition as defined
24475
    * by Datatype Valid in [XML Schemas: Datatypes].
24476
    */
24477
    /*
24478
    * 2.1 If The definition is ENTITY or is validly derived from ENTITY given
24479
    * the empty set, as defined in Type Derivation OK (Simple) ($3.14.6), then
24480
    * the string must be a `declared entity name`.
24481
    */
24482
    /*
24483
    * 2.2 If The definition is ENTITIES or is validly derived from ENTITIES
24484
    * given the empty set, as defined in Type Derivation OK (Simple) ($3.14.6),
24485
    * then every whitespace-delimited substring of the string must be a `declared
24486
    * entity name`.
24487
    */
24488
    /*
24489
    * 2.3 otherwise no further condition applies.
24490
    */
24491
0
    if ((! valNeeded) && (type->flags & XML_SCHEMAS_TYPE_FACETSNEEDVALUE))
24492
0
  valNeeded = 1;
24493
0
    if (value == NULL)
24494
0
  value = BAD_CAST "";
24495
0
    if (WXS_IS_ANY_SIMPLE_TYPE(type) || WXS_IS_ATOMIC(type)) {
24496
0
  xmlSchemaTypePtr biType; /* The built-in type. */
24497
  /*
24498
  * SPEC (1.2.1) "if {variety} is `atomic` then the string must `match`
24499
  * a literal in the `lexical space` of {base type definition}"
24500
  */
24501
  /*
24502
  * Whitespace-normalize.
24503
  */
24504
0
  NORMALIZE(type);
24505
0
  if (type->type != XML_SCHEMA_TYPE_BASIC) {
24506
      /*
24507
      * Get the built-in type.
24508
      */
24509
0
      biType = type->baseType;
24510
0
      while ((biType != NULL) &&
24511
0
    (biType->type != XML_SCHEMA_TYPE_BASIC))
24512
0
    biType = biType->baseType;
24513
24514
0
      if (biType == NULL) {
24515
0
    AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24516
0
        "could not get the built-in type");
24517
0
    goto internal_error;
24518
0
      }
24519
0
  } else
24520
0
      biType = type;
24521
  /*
24522
  * NOTATIONs need to be processed here, since they need
24523
  * to lookup in the hashtable of NOTATION declarations of the schema.
24524
  */
24525
0
  if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR) {
24526
0
      switch (biType->builtInType) {
24527
0
    case XML_SCHEMAS_NOTATION:
24528
0
        ret = xmlSchemaValidateNotation(
24529
0
      (xmlSchemaValidCtxtPtr) actxt,
24530
0
      ((xmlSchemaValidCtxtPtr) actxt)->schema,
24531
0
      NULL, value, &val, valNeeded);
24532
0
        break;
24533
0
    case XML_SCHEMAS_QNAME:
24534
0
        ret = xmlSchemaValidateQName((xmlSchemaValidCtxtPtr) actxt,
24535
0
      value, &val, valNeeded);
24536
0
        break;
24537
0
    default:
24538
        /* ws = xmlSchemaGetWhiteSpaceFacetValue(type); */
24539
0
        if (valNeeded)
24540
0
      ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
24541
0
          value, &val, node);
24542
0
        else
24543
0
      ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
24544
0
          value, NULL, node);
24545
0
        break;
24546
0
      }
24547
0
  } else if (actxt->type == XML_SCHEMA_CTXT_PARSER) {
24548
0
      switch (biType->builtInType) {
24549
0
    case XML_SCHEMAS_NOTATION:
24550
0
        ret = xmlSchemaValidateNotation(NULL,
24551
0
      ((xmlSchemaParserCtxtPtr) actxt)->schema, node,
24552
0
      value, &val, valNeeded);
24553
0
        break;
24554
0
    default:
24555
        /* ws = xmlSchemaGetWhiteSpaceFacetValue(type); */
24556
0
        if (valNeeded)
24557
0
      ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
24558
0
          value, &val, node);
24559
0
        else
24560
0
      ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
24561
0
          value, NULL, node);
24562
0
        break;
24563
0
      }
24564
0
  } else {
24565
      /*
24566
      * Validation via a public API is not implemented yet.
24567
      */
24568
0
      goto internal_error;
24569
0
  }
24570
0
  if (ret != 0) {
24571
0
      if (ret < 0) {
24572
0
    AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24573
0
        "validating against a built-in type");
24574
0
    goto internal_error;
24575
0
      }
24576
0
      if (WXS_IS_LIST(type))
24577
0
    ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
24578
0
      else
24579
0
    ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
24580
0
  }
24581
0
  if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) {
24582
      /*
24583
      * Check facets.
24584
      */
24585
0
      ret = xmlSchemaValidateFacets(actxt, node, type,
24586
0
    (xmlSchemaValType) biType->builtInType, value, val,
24587
0
    0, fireErrors);
24588
0
      if (ret != 0) {
24589
0
    if (ret < 0) {
24590
0
        AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24591
0
      "validating facets of atomic simple type");
24592
0
        goto internal_error;
24593
0
    }
24594
0
    if (WXS_IS_LIST(type))
24595
0
        ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
24596
0
    else
24597
0
        ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
24598
0
      }
24599
0
  }
24600
0
  else if (fireErrors && (ret > 0))
24601
0
      xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1);
24602
0
    } else if (WXS_IS_LIST(type)) {
24603
24604
0
  xmlSchemaTypePtr itemType;
24605
0
  const xmlChar *cur, *end;
24606
0
  xmlChar *tmpValue = NULL;
24607
0
  unsigned long len = 0;
24608
0
  xmlSchemaValPtr prevVal = NULL, curVal = NULL;
24609
  /* 1.2.2 if {variety} is `list` then the string must be a sequence
24610
  * of white space separated tokens, each of which `match`es a literal
24611
  * in the `lexical space` of {item type definition}
24612
  */
24613
  /*
24614
  * Note that XML_SCHEMAS_TYPE_NORMVALUENEEDED will be set if
24615
  * the list type has an enum or pattern facet.
24616
  */
24617
0
  NORMALIZE(type);
24618
  /*
24619
  * VAL TODO: Optimize validation of empty values.
24620
  * VAL TODO: We do not have computed values for lists.
24621
  */
24622
0
  itemType = WXS_LIST_ITEMTYPE(type);
24623
0
  cur = value;
24624
0
  do {
24625
0
      while (IS_BLANK_CH(*cur))
24626
0
    cur++;
24627
0
      end = cur;
24628
0
      while ((*end != 0) && (!(IS_BLANK_CH(*end))))
24629
0
    end++;
24630
0
      if (end == cur)
24631
0
    break;
24632
0
      tmpValue = xmlStrndup(cur, end - cur);
24633
0
      len++;
24634
24635
0
      if (valNeeded)
24636
0
    ret = xmlSchemaVCheckCVCSimpleType(actxt, node, itemType,
24637
0
        tmpValue, &curVal, fireErrors, 0, 1);
24638
0
      else
24639
0
    ret = xmlSchemaVCheckCVCSimpleType(actxt, node, itemType,
24640
0
        tmpValue, NULL, fireErrors, 0, 1);
24641
0
      FREE_AND_NULL(tmpValue);
24642
0
      if (curVal != NULL) {
24643
    /*
24644
    * Add to list of computed values.
24645
    */
24646
0
    if (val == NULL)
24647
0
        val = curVal;
24648
0
    else
24649
0
        xmlSchemaValueAppend(prevVal, curVal);
24650
0
    prevVal = curVal;
24651
0
    curVal = NULL;
24652
0
      }
24653
0
      if (ret != 0) {
24654
0
    if (ret < 0) {
24655
0
        AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24656
0
      "validating an item of list simple type");
24657
0
        goto internal_error;
24658
0
    }
24659
0
    ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
24660
0
    break;
24661
0
      }
24662
0
      cur = end;
24663
0
  } while (*cur != 0);
24664
0
  FREE_AND_NULL(tmpValue);
24665
0
  if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) {
24666
      /*
24667
      * Apply facets (pattern, enumeration).
24668
      */
24669
0
      ret = xmlSchemaValidateFacets(actxt, node, type,
24670
0
    XML_SCHEMAS_UNKNOWN, value, val,
24671
0
    len, fireErrors);
24672
0
      if (ret != 0) {
24673
0
    if (ret < 0) {
24674
0
        AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24675
0
      "validating facets of list simple type");
24676
0
        goto internal_error;
24677
0
    }
24678
0
    ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
24679
0
      }
24680
0
  }
24681
0
  if (fireErrors && (ret > 0)) {
24682
      /*
24683
      * Report the normalized value.
24684
      */
24685
0
      normalize = 1;
24686
0
      NORMALIZE(type);
24687
0
      xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1);
24688
0
  }
24689
0
    } else if (WXS_IS_UNION(type)) {
24690
0
  xmlSchemaTypeLinkPtr memberLink;
24691
  /*
24692
  * TODO: For all datatypes `derived` by `union`  whiteSpace does
24693
  * not apply directly; however, the normalization behavior of `union`
24694
  * types is controlled by the value of whiteSpace on that one of the
24695
  * `memberTypes` against which the `union` is successfully validated.
24696
  *
24697
  * This means that the value is normalized by the first validating
24698
  * member type, then the facets of the union type are applied. This
24699
  * needs changing of the value!
24700
  */
24701
24702
  /*
24703
  * 1.2.3 if {variety} is `union` then the string must `match` a
24704
  * literal in the `lexical space` of at least one member of
24705
  * {member type definitions}
24706
  */
24707
0
  memberLink = xmlSchemaGetUnionSimpleTypeMemberTypes(type);
24708
0
  if (memberLink == NULL) {
24709
0
      AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24710
0
    "union simple type has no member types");
24711
0
      goto internal_error;
24712
0
  }
24713
  /*
24714
  * Always normalize union type values, since we currently
24715
  * cannot store the whitespace information with the value
24716
  * itself; otherwise a later value-comparison would be
24717
  * not possible.
24718
  */
24719
0
  while (memberLink != NULL) {
24720
0
      if (valNeeded)
24721
0
    ret = xmlSchemaVCheckCVCSimpleType(actxt, node,
24722
0
        memberLink->type, value, &val, 0, 1, 0);
24723
0
      else
24724
0
    ret = xmlSchemaVCheckCVCSimpleType(actxt, node,
24725
0
        memberLink->type, value, NULL, 0, 1, 0);
24726
0
      if (ret <= 0)
24727
0
    break;
24728
0
      memberLink = memberLink->next;
24729
0
  }
24730
0
  if (ret != 0) {
24731
0
      if (ret < 0) {
24732
0
    AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24733
0
        "validating members of union simple type");
24734
0
    goto internal_error;
24735
0
      }
24736
0
      ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_3;
24737
0
  }
24738
  /*
24739
  * Apply facets (pattern, enumeration).
24740
  */
24741
0
  if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) {
24742
      /*
24743
      * The normalization behavior of `union` types is controlled by
24744
      * the value of whiteSpace on that one of the `memberTypes`
24745
      * against which the `union` is successfully validated.
24746
      */
24747
0
      NORMALIZE(memberLink->type);
24748
0
      ret = xmlSchemaValidateFacets(actxt, node, type,
24749
0
    XML_SCHEMAS_UNKNOWN, value, val,
24750
0
    0, fireErrors);
24751
0
      if (ret != 0) {
24752
0
    if (ret < 0) {
24753
0
        AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24754
0
      "validating facets of union simple type");
24755
0
        goto internal_error;
24756
0
    }
24757
0
    ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_3;
24758
0
      }
24759
0
  }
24760
0
  if (fireErrors && (ret > 0))
24761
0
      xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1);
24762
0
    }
24763
24764
0
    if (normValue != NULL)
24765
0
  xmlFree(normValue);
24766
0
    if (ret == 0) {
24767
0
  if (retVal != NULL)
24768
0
      *retVal = val;
24769
0
  else if (val != NULL)
24770
0
      xmlSchemaFreeValue(val);
24771
0
    } else if (val != NULL)
24772
0
  xmlSchemaFreeValue(val);
24773
0
    return (ret);
24774
0
internal_error:
24775
0
    if (normValue != NULL)
24776
0
  xmlFree(normValue);
24777
0
    if (val != NULL)
24778
0
  xmlSchemaFreeValue(val);
24779
0
    return (-1);
24780
0
}
24781
24782
static int
24783
xmlSchemaVExpandQName(xmlSchemaValidCtxtPtr vctxt,
24784
         const xmlChar *value,
24785
         const xmlChar **nsName,
24786
         const xmlChar **localName)
24787
0
{
24788
0
    int ret = 0;
24789
24790
0
    if ((nsName == NULL) || (localName == NULL))
24791
0
  return (-1);
24792
0
    *nsName = NULL;
24793
0
    *localName = NULL;
24794
24795
0
    ret = xmlValidateQName(value, 1);
24796
0
    if (ret == -1)
24797
0
  return (-1);
24798
0
    if (ret > 0) {
24799
0
  xmlSchemaSimpleTypeErr(ACTXT_CAST vctxt,
24800
0
      XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1, NULL,
24801
0
      value, xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), 1);
24802
0
  return (1);
24803
0
    }
24804
0
    {
24805
0
  xmlChar *local = NULL;
24806
0
  xmlChar *prefix;
24807
24808
  /*
24809
  * NOTE: xmlSplitQName2 will return a duplicated
24810
  * string.
24811
  */
24812
0
  local = xmlSplitQName2(value, &prefix);
24813
0
  if (local == NULL)
24814
0
      *localName = xmlDictLookup(vctxt->dict, value, -1);
24815
0
  else {
24816
0
      *localName = xmlDictLookup(vctxt->dict, local, -1);
24817
0
      xmlFree(local);
24818
0
  }
24819
24820
0
  *nsName = xmlSchemaLookupNamespace(vctxt, prefix);
24821
24822
0
  if (prefix != NULL) {
24823
0
      xmlFree(prefix);
24824
      /*
24825
      * A namespace must be found if the prefix is NOT NULL.
24826
      */
24827
0
      if (*nsName == NULL) {
24828
0
    xmlSchemaCustomErr(ACTXT_CAST vctxt,
24829
0
        XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1, NULL,
24830
0
        WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
24831
0
        "The QName value '%s' has no "
24832
0
        "corresponding namespace declaration in scope",
24833
0
        value, NULL);
24834
0
    return (2);
24835
0
      }
24836
0
  }
24837
0
    }
24838
0
    return (0);
24839
0
}
24840
24841
static int
24842
xmlSchemaProcessXSIType(xmlSchemaValidCtxtPtr vctxt,
24843
      xmlSchemaAttrInfoPtr iattr,
24844
      xmlSchemaTypePtr *localType,
24845
      xmlSchemaElementPtr elemDecl)
24846
0
{
24847
0
    int ret = 0;
24848
    /*
24849
    * cvc-elt (3.3.4) : (4)
24850
    * AND
24851
    * Schema-Validity Assessment (Element) (cvc-assess-elt)
24852
    *   (1.2.1.2.1) - (1.2.1.2.4)
24853
    * Handle 'xsi:type'.
24854
    */
24855
0
    if (localType == NULL)
24856
0
  return (-1);
24857
0
    *localType = NULL;
24858
0
    if (iattr == NULL)
24859
0
  return (0);
24860
0
    else {
24861
0
  const xmlChar *nsName = NULL, *local = NULL;
24862
  /*
24863
  * TODO: We should report a *warning* that the type was overridden
24864
  * by the instance.
24865
  */
24866
0
  ACTIVATE_ATTRIBUTE(iattr);
24867
  /*
24868
  * (cvc-elt) (3.3.4) : (4.1)
24869
  * (cvc-assess-elt) (1.2.1.2.2)
24870
  */
24871
0
  ret = xmlSchemaVExpandQName(vctxt, iattr->value,
24872
0
      &nsName, &local);
24873
0
  if (ret != 0) {
24874
0
      if (ret < 0) {
24875
0
    VERROR_INT("xmlSchemaValidateElementByDeclaration",
24876
0
        "calling xmlSchemaQNameExpand() to validate the "
24877
0
        "attribute 'xsi:type'");
24878
0
    goto internal_error;
24879
0
      }
24880
0
      goto exit;
24881
0
  }
24882
  /*
24883
  * (cvc-elt) (3.3.4) : (4.2)
24884
  * (cvc-assess-elt) (1.2.1.2.3)
24885
  */
24886
0
  *localType = xmlSchemaGetType(vctxt->schema, local, nsName);
24887
0
  if (*localType == NULL) {
24888
0
      xmlChar *str = NULL;
24889
24890
0
      xmlSchemaCustomErr(ACTXT_CAST vctxt,
24891
0
    XML_SCHEMAV_CVC_ELT_4_2, NULL,
24892
0
    WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
24893
0
    "The QName value '%s' of the xsi:type attribute does not "
24894
0
    "resolve to a type definition",
24895
0
    xmlSchemaFormatQName(&str, nsName, local), NULL);
24896
0
      FREE_AND_NULL(str);
24897
0
      ret = vctxt->err;
24898
0
      goto exit;
24899
0
  }
24900
0
  if (elemDecl != NULL) {
24901
0
      int set = 0;
24902
24903
      /*
24904
      * SPEC cvc-elt (3.3.4) : (4.3) (Type Derivation OK)
24905
      * "The `local type definition` must be validly
24906
      * derived from the {type definition} given the union of
24907
      * the {disallowed substitutions} and the {type definition}'s
24908
      * {prohibited substitutions}, as defined in
24909
      * Type Derivation OK (Complex) ($3.4.6)
24910
      * (if it is a complex type definition),
24911
      * or given {disallowed substitutions} as defined in Type
24912
      * Derivation OK (Simple) ($3.14.6) (if it is a simple type
24913
      * definition)."
24914
      *
24915
      * {disallowed substitutions}: the "block" on the element decl.
24916
      * {prohibited substitutions}: the "block" on the type def.
24917
      */
24918
      /*
24919
      * OPTIMIZE TODO: We could map types already evaluated
24920
      * to be validly derived from other types to avoid checking
24921
      * this over and over for the same types.
24922
      */
24923
0
      if ((elemDecl->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) ||
24924
0
    (elemDecl->subtypes->flags &
24925
0
        XML_SCHEMAS_TYPE_BLOCK_EXTENSION))
24926
0
    set |= SUBSET_EXTENSION;
24927
24928
0
      if ((elemDecl->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) ||
24929
0
    (elemDecl->subtypes->flags &
24930
0
        XML_SCHEMAS_TYPE_BLOCK_RESTRICTION))
24931
0
    set |= SUBSET_RESTRICTION;
24932
24933
      /*
24934
      * REMOVED and CHANGED since this produced a parser context
24935
      * which adds to the string dict of the schema. So this would
24936
      * change the schema and we don't want this. We don't need
24937
      * the parser context anymore.
24938
      *
24939
      * if ((vctxt->pctxt == NULL) &&
24940
      * (xmlSchemaCreatePCtxtOnVCtxt(vctxt) == -1))
24941
      *     return (-1);
24942
      */
24943
24944
0
      if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST vctxt, *localType,
24945
0
    elemDecl->subtypes, set) != 0) {
24946
0
    xmlChar *str = NULL;
24947
24948
0
    xmlSchemaCustomErr(ACTXT_CAST vctxt,
24949
0
        XML_SCHEMAV_CVC_ELT_4_3, NULL, NULL,
24950
0
        "The type definition '%s', specified by xsi:type, is "
24951
0
        "blocked or not validly derived from the type definition "
24952
0
        "of the element declaration",
24953
0
        xmlSchemaFormatQName(&str,
24954
0
      (*localType)->targetNamespace,
24955
0
      (*localType)->name),
24956
0
        NULL);
24957
0
    FREE_AND_NULL(str);
24958
0
    ret = vctxt->err;
24959
0
    *localType = NULL;
24960
0
      }
24961
0
  }
24962
0
    }
24963
0
exit:
24964
0
    ACTIVATE_ELEM;
24965
0
    return (ret);
24966
0
internal_error:
24967
0
    ACTIVATE_ELEM;
24968
0
    return (-1);
24969
0
}
24970
24971
static int
24972
xmlSchemaValidateElemDecl(xmlSchemaValidCtxtPtr vctxt)
24973
0
{
24974
0
    xmlSchemaElementPtr elemDecl = vctxt->inode->decl;
24975
0
    xmlSchemaTypePtr actualType;
24976
24977
    /*
24978
    * cvc-elt (3.3.4) : 1
24979
    */
24980
0
    if (elemDecl == NULL) {
24981
0
  VERROR(XML_SCHEMAV_CVC_ELT_1, NULL,
24982
0
      "No matching declaration available");
24983
0
        return (vctxt->err);
24984
0
    }
24985
0
    actualType = WXS_ELEM_TYPEDEF(elemDecl);
24986
    /*
24987
    * cvc-elt (3.3.4) : 2
24988
    */
24989
0
    if (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT) {
24990
0
  VERROR(XML_SCHEMAV_CVC_ELT_2, NULL,
24991
0
      "The element declaration is abstract");
24992
0
        return (vctxt->err);
24993
0
    }
24994
0
    if (actualType == NULL) {
24995
0
  VERROR(XML_SCHEMAV_CVC_TYPE_1, NULL,
24996
0
      "The type definition is absent");
24997
0
  return (XML_SCHEMAV_CVC_TYPE_1);
24998
0
    }
24999
0
    if (vctxt->nbAttrInfos != 0) {
25000
0
  int ret;
25001
0
  xmlSchemaAttrInfoPtr iattr;
25002
  /*
25003
  * cvc-elt (3.3.4) : 3
25004
  * Handle 'xsi:nil'.
25005
  */
25006
0
  iattr = xmlSchemaGetMetaAttrInfo(vctxt,
25007
0
      XML_SCHEMA_ATTR_INFO_META_XSI_NIL);
25008
0
  if (iattr) {
25009
0
      ACTIVATE_ATTRIBUTE(iattr);
25010
      /*
25011
      * Validate the value.
25012
      */
25013
0
      ret = xmlSchemaVCheckCVCSimpleType(
25014
0
    ACTXT_CAST vctxt, NULL,
25015
0
    xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN),
25016
0
    iattr->value, &(iattr->val), 1, 0, 0);
25017
0
      ACTIVATE_ELEM;
25018
0
      if (ret < 0) {
25019
0
    VERROR_INT("xmlSchemaValidateElemDecl",
25020
0
        "calling xmlSchemaVCheckCVCSimpleType() to "
25021
0
        "validate the attribute 'xsi:nil'");
25022
0
    return (-1);
25023
0
      }
25024
0
      if (ret == 0) {
25025
0
    if ((elemDecl->flags & XML_SCHEMAS_ELEM_NILLABLE) == 0) {
25026
        /*
25027
        * cvc-elt (3.3.4) : 3.1
25028
        */
25029
0
        VERROR(XML_SCHEMAV_CVC_ELT_3_1, NULL,
25030
0
      "The element is not 'nillable'");
25031
        /* Does not return an error on purpose. */
25032
0
    } else {
25033
0
        if (xmlSchemaValueGetAsBoolean(iattr->val)) {
25034
      /*
25035
      * cvc-elt (3.3.4) : 3.2.2
25036
      */
25037
0
      if ((elemDecl->flags & XML_SCHEMAS_ELEM_FIXED) &&
25038
0
          (elemDecl->value != NULL)) {
25039
0
          VERROR(XML_SCHEMAV_CVC_ELT_3_2_2, NULL,
25040
0
        "The element cannot be 'nilled' because "
25041
0
        "there is a fixed value constraint defined "
25042
0
        "for it");
25043
           /* Does not return an error on purpose. */
25044
0
      } else
25045
0
          vctxt->inode->flags |=
25046
0
        XML_SCHEMA_ELEM_INFO_NILLED;
25047
0
        }
25048
0
    }
25049
0
      }
25050
0
  }
25051
  /*
25052
  * cvc-elt (3.3.4) : 4
25053
  * Handle 'xsi:type'.
25054
  */
25055
0
  iattr = xmlSchemaGetMetaAttrInfo(vctxt,
25056
0
      XML_SCHEMA_ATTR_INFO_META_XSI_TYPE);
25057
0
  if (iattr) {
25058
0
      xmlSchemaTypePtr localType = NULL;
25059
25060
0
      ret = xmlSchemaProcessXSIType(vctxt, iattr, &localType,
25061
0
    elemDecl);
25062
0
      if (ret != 0) {
25063
0
    if (ret == -1) {
25064
0
        VERROR_INT("xmlSchemaValidateElemDecl",
25065
0
      "calling xmlSchemaProcessXSIType() to "
25066
0
      "process the attribute 'xsi:type'");
25067
0
        return (-1);
25068
0
    }
25069
    /* Does not return an error on purpose. */
25070
0
      }
25071
0
      if (localType != NULL) {
25072
0
    vctxt->inode->flags |= XML_SCHEMA_ELEM_INFO_LOCAL_TYPE;
25073
0
    actualType = localType;
25074
0
      }
25075
0
  }
25076
0
    }
25077
    /*
25078
    * IDC: Register identity-constraint XPath matchers.
25079
    */
25080
0
    if ((elemDecl->idcs != NULL) &&
25081
0
  (xmlSchemaIDCRegisterMatchers(vctxt, elemDecl) == -1))
25082
0
      return (-1);
25083
    /*
25084
    * No actual type definition.
25085
    */
25086
0
    if (actualType == NULL) {
25087
0
  VERROR(XML_SCHEMAV_CVC_TYPE_1, NULL,
25088
0
      "The type definition is absent");
25089
0
  return (XML_SCHEMAV_CVC_TYPE_1);
25090
0
    }
25091
    /*
25092
    * Remember the actual type definition.
25093
    */
25094
0
    vctxt->inode->typeDef = actualType;
25095
25096
0
    return (0);
25097
0
}
25098
25099
static int
25100
xmlSchemaVAttributesSimple(xmlSchemaValidCtxtPtr vctxt)
25101
0
{
25102
0
    xmlSchemaAttrInfoPtr iattr;
25103
0
    int ret = 0, i;
25104
25105
    /*
25106
    * SPEC cvc-type (3.1.1)
25107
    * "The attributes of must be empty, excepting those whose namespace
25108
    * name is identical to http://www.w3.org/2001/XMLSchema-instance and
25109
    * whose local name is one of type, nil, schemaLocation or
25110
    * noNamespaceSchemaLocation."
25111
    */
25112
0
    if (vctxt->nbAttrInfos == 0)
25113
0
  return (0);
25114
0
    for (i = 0; i < vctxt->nbAttrInfos; i++) {
25115
0
  iattr = vctxt->attrInfos[i];
25116
0
  if (! iattr->metaType) {
25117
0
      ACTIVATE_ATTRIBUTE(iattr)
25118
0
      xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt,
25119
0
    XML_SCHEMAV_CVC_TYPE_3_1_1, iattr, NULL);
25120
0
      ret = XML_SCHEMAV_CVC_TYPE_3_1_1;
25121
0
        }
25122
0
    }
25123
0
    ACTIVATE_ELEM
25124
0
    return (ret);
25125
0
}
25126
25127
/*
25128
* Cleanup currently used attribute infos.
25129
*/
25130
static void
25131
xmlSchemaClearAttrInfos(xmlSchemaValidCtxtPtr vctxt)
25132
0
{
25133
0
    int i;
25134
0
    xmlSchemaAttrInfoPtr attr;
25135
25136
0
    if (vctxt->nbAttrInfos == 0)
25137
0
  return;
25138
0
    for (i = 0; i < vctxt->nbAttrInfos; i++) {
25139
0
  attr = vctxt->attrInfos[i];
25140
0
  if (attr->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES) {
25141
0
      if (attr->localName != NULL)
25142
0
    xmlFree((xmlChar *) attr->localName);
25143
0
      if (attr->nsName != NULL)
25144
0
    xmlFree((xmlChar *) attr->nsName);
25145
0
  }
25146
0
  if (attr->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) {
25147
0
      if (attr->value != NULL)
25148
0
    xmlFree((xmlChar *) attr->value);
25149
0
  }
25150
0
  if (attr->val != NULL) {
25151
0
      xmlSchemaFreeValue(attr->val);
25152
0
      attr->val = NULL;
25153
0
  }
25154
0
  memset(attr, 0, sizeof(xmlSchemaAttrInfo));
25155
0
    }
25156
0
    vctxt->nbAttrInfos = 0;
25157
0
}
25158
25159
/*
25160
* 3.4.4 Complex Type Definition Validation Rules
25161
*   Element Locally Valid (Complex Type) (cvc-complex-type)
25162
* 3.2.4 Attribute Declaration Validation Rules
25163
*   Validation Rule: Attribute Locally Valid (cvc-attribute)
25164
*   Attribute Locally Valid (Use) (cvc-au)
25165
*
25166
* Only "assessed" attribute information items will be visible to
25167
* IDCs. I.e. not "lax" (without declaration) and "skip" wild attributes.
25168
*/
25169
static int
25170
xmlSchemaVAttributesComplex(xmlSchemaValidCtxtPtr vctxt)
25171
0
{
25172
0
    xmlSchemaTypePtr type = vctxt->inode->typeDef;
25173
0
    xmlSchemaItemListPtr attrUseList;
25174
0
    xmlSchemaAttributeUsePtr attrUse = NULL;
25175
0
    xmlSchemaAttributePtr attrDecl = NULL;
25176
0
    xmlSchemaAttrInfoPtr iattr, tmpiattr;
25177
0
    int i, j, found, nbAttrs, nbUses;
25178
0
    int xpathRes = 0, res, wildIDs = 0, fixed;
25179
0
    xmlNodePtr defAttrOwnerElem = NULL;
25180
25181
    /*
25182
    * SPEC (cvc-attribute)
25183
    * (1) "The declaration must not be `absent` (see Missing
25184
    * Sub-components ($5.3) for how this can fail to be
25185
    * the case)."
25186
    * (2) "Its {type definition} must not be absent."
25187
    *
25188
    * NOTE (1) + (2): This is not handled here, since we currently do not
25189
    * allow validation against schemas which have missing sub-components.
25190
    *
25191
    * SPEC (cvc-complex-type)
25192
    * (3) "For each attribute information item in the element information
25193
    * item's [attributes] excepting those whose [namespace name] is
25194
    * identical to http://www.w3.org/2001/XMLSchema-instance and whose
25195
    * [local name] is one of type, nil, schemaLocation or
25196
    * noNamespaceSchemaLocation, the appropriate case among the following
25197
    * must be true:
25198
    *
25199
    */
25200
0
    attrUseList = (xmlSchemaItemListPtr) type->attrUses;
25201
    /*
25202
    * @nbAttrs is the number of attributes present in the instance.
25203
    */
25204
0
    nbAttrs = vctxt->nbAttrInfos;
25205
0
    if (attrUseList != NULL)
25206
0
  nbUses = attrUseList->nbItems;
25207
0
    else
25208
0
  nbUses = 0;
25209
0
    for (i = 0; i < nbUses; i++) {
25210
0
        found = 0;
25211
0
  attrUse = attrUseList->items[i];
25212
0
  attrDecl = WXS_ATTRUSE_DECL(attrUse);
25213
0
        for (j = 0; j < nbAttrs; j++) {
25214
0
      iattr = vctxt->attrInfos[j];
25215
      /*
25216
      * SPEC (cvc-complex-type) (3)
25217
      * Skip meta attributes.
25218
      */
25219
0
      if (iattr->metaType)
25220
0
    continue;
25221
0
      if (iattr->localName[0] != attrDecl->name[0])
25222
0
    continue;
25223
0
      if (!xmlStrEqual(iattr->localName, attrDecl->name))
25224
0
    continue;
25225
0
      if (!xmlStrEqual(iattr->nsName, attrDecl->targetNamespace))
25226
0
    continue;
25227
0
      found = 1;
25228
      /*
25229
      * SPEC (cvc-complex-type)
25230
      * (3.1) "If there is among the {attribute uses} an attribute
25231
      * use with an {attribute declaration} whose {name} matches
25232
      * the attribute information item's [local name] and whose
25233
      * {target namespace} is identical to the attribute information
25234
      * item's [namespace name] (where an `absent` {target namespace}
25235
      * is taken to be identical to a [namespace name] with no value),
25236
      * then the attribute information must be `valid` with respect
25237
      * to that attribute use as per Attribute Locally Valid (Use)
25238
      * ($3.5.4). In this case the {attribute declaration} of that
25239
      * attribute use is the `context-determined declaration` for the
25240
      * attribute information item with respect to Schema-Validity
25241
      * Assessment (Attribute) ($3.2.4) and
25242
      * Assessment Outcome (Attribute) ($3.2.5).
25243
      */
25244
0
      iattr->state = XML_SCHEMAS_ATTR_ASSESSED;
25245
0
      iattr->use = attrUse;
25246
      /*
25247
      * Context-determined declaration.
25248
      */
25249
0
      iattr->decl = attrDecl;
25250
0
      iattr->typeDef = attrDecl->subtypes;
25251
0
      break;
25252
0
  }
25253
25254
0
  if (found)
25255
0
      continue;
25256
25257
0
  if (attrUse->occurs == XML_SCHEMAS_ATTR_USE_REQUIRED) {
25258
      /*
25259
      * Handle non-existent, required attributes.
25260
      *
25261
      * SPEC (cvc-complex-type)
25262
      * (4) "The {attribute declaration} of each attribute use in
25263
      * the {attribute uses} whose {required} is true matches one
25264
      * of the attribute information items in the element information
25265
      * item's [attributes] as per clause 3.1 above."
25266
      */
25267
0
      tmpiattr = xmlSchemaGetFreshAttrInfo(vctxt);
25268
0
      if (tmpiattr == NULL) {
25269
0
    VERROR_INT(
25270
0
        "xmlSchemaVAttributesComplex",
25271
0
        "calling xmlSchemaGetFreshAttrInfo()");
25272
0
    return (-1);
25273
0
      }
25274
0
      tmpiattr->state = XML_SCHEMAS_ATTR_ERR_MISSING;
25275
0
      tmpiattr->use = attrUse;
25276
0
      tmpiattr->decl = attrDecl;
25277
0
  } else if ((attrUse->occurs == XML_SCHEMAS_ATTR_USE_OPTIONAL) &&
25278
0
      ((attrUse->defValue != NULL) ||
25279
0
       (attrDecl->defValue != NULL))) {
25280
      /*
25281
      * Handle non-existent, optional, default/fixed attributes.
25282
      */
25283
0
      tmpiattr = xmlSchemaGetFreshAttrInfo(vctxt);
25284
0
      if (tmpiattr == NULL) {
25285
0
    VERROR_INT(
25286
0
        "xmlSchemaVAttributesComplex",
25287
0
        "calling xmlSchemaGetFreshAttrInfo()");
25288
0
    return (-1);
25289
0
      }
25290
0
      tmpiattr->state = XML_SCHEMAS_ATTR_DEFAULT;
25291
0
      tmpiattr->use = attrUse;
25292
0
      tmpiattr->decl = attrDecl;
25293
0
      tmpiattr->typeDef = attrDecl->subtypes;
25294
0
      tmpiattr->localName = attrDecl->name;
25295
0
      tmpiattr->nsName = attrDecl->targetNamespace;
25296
0
  }
25297
0
    }
25298
25299
0
    if (vctxt->nbAttrInfos == 0)
25300
0
  return (0);
25301
    /*
25302
    * Validate against the wildcard.
25303
    */
25304
0
    if (type->attributeWildcard != NULL) {
25305
  /*
25306
  * SPEC (cvc-complex-type)
25307
  * (3.2.1) "There must be an {attribute wildcard}."
25308
  */
25309
0
  for (i = 0; i < nbAttrs; i++) {
25310
0
      iattr = vctxt->attrInfos[i];
25311
      /*
25312
      * SPEC (cvc-complex-type) (3)
25313
      * Skip meta attributes.
25314
      */
25315
0
      if (iattr->state != XML_SCHEMAS_ATTR_UNKNOWN)
25316
0
    continue;
25317
      /*
25318
      * SPEC (cvc-complex-type)
25319
      * (3.2.2) "The attribute information item must be `valid` with
25320
      * respect to it as defined in Item Valid (Wildcard) ($3.10.4)."
25321
      *
25322
      * SPEC Item Valid (Wildcard) (cvc-wildcard)
25323
      * "... its [namespace name] must be `valid` with respect to
25324
      * the wildcard constraint, as defined in Wildcard allows
25325
      * Namespace Name ($3.10.4)."
25326
      */
25327
0
      if (xmlSchemaCheckCVCWildcardNamespace(type->attributeWildcard,
25328
0
        iattr->nsName) == 0) {
25329
    /*
25330
    * Handle processContents.
25331
    *
25332
    * SPEC (cvc-wildcard):
25333
    * processContents | context-determined declaration:
25334
    * "strict"          "mustFind"
25335
    * "lax"             "none"
25336
    * "skip"            "skip"
25337
    */
25338
0
    if (type->attributeWildcard->processContents ==
25339
0
        XML_SCHEMAS_ANY_SKIP) {
25340
         /*
25341
        * context-determined declaration = "skip"
25342
        *
25343
        * SPEC PSVI Assessment Outcome (Attribute)
25344
        * [validity] = "notKnown"
25345
        * [validation attempted] = "none"
25346
        */
25347
0
        iattr->state = XML_SCHEMAS_ATTR_WILD_SKIP;
25348
0
        continue;
25349
0
    }
25350
    /*
25351
    * Find an attribute declaration.
25352
    */
25353
0
    iattr->decl = xmlSchemaGetAttributeDecl(vctxt->schema,
25354
0
        iattr->localName, iattr->nsName);
25355
0
    if (iattr->decl != NULL) {
25356
0
        iattr->state = XML_SCHEMAS_ATTR_ASSESSED;
25357
        /*
25358
        * SPEC (cvc-complex-type)
25359
        * (5) "Let [Definition:]  the wild IDs be the set of
25360
        * all attribute information item to which clause 3.2
25361
        * applied and whose `validation` resulted in a
25362
        * `context-determined declaration` of mustFind or no
25363
        * `context-determined declaration` at all, and whose
25364
        * [local name] and [namespace name] resolve (as
25365
        * defined by QName resolution (Instance) ($3.15.4)) to
25366
        * an attribute declaration whose {type definition} is
25367
        * or is derived from ID. Then all of the following
25368
        * must be true:"
25369
        */
25370
0
        iattr->typeDef = WXS_ATTR_TYPEDEF(iattr->decl);
25371
0
        if (xmlSchemaIsDerivedFromBuiltInType(
25372
0
      iattr->typeDef, XML_SCHEMAS_ID)) {
25373
      /*
25374
      * SPEC (5.1) "There must be no more than one
25375
      * item in `wild IDs`."
25376
      */
25377
0
      if (wildIDs != 0) {
25378
          /* VAL TODO */
25379
0
          iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_DUPLICATE_ID;
25380
0
          continue;
25381
0
      }
25382
0
      wildIDs++;
25383
      /*
25384
      * SPEC (cvc-complex-type)
25385
      * (5.2) "If `wild IDs` is non-empty, there must not
25386
      * be any attribute uses among the {attribute uses}
25387
      * whose {attribute declaration}'s {type definition}
25388
      * is or is derived from ID."
25389
      */
25390
0
                        if (attrUseList != NULL) {
25391
0
                            for (j = 0; j < attrUseList->nbItems; j++) {
25392
0
                                if (xmlSchemaIsDerivedFromBuiltInType(
25393
0
                                    WXS_ATTRUSE_TYPEDEF(attrUseList->items[j]),
25394
0
                                    XML_SCHEMAS_ID)) {
25395
                                    /* URGENT VAL TODO: implement */
25396
0
                            iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_AND_USE_ID;
25397
0
                                    break;
25398
0
                                }
25399
0
                            }
25400
0
                        }
25401
0
        }
25402
0
    } else if (type->attributeWildcard->processContents ==
25403
0
        XML_SCHEMAS_ANY_LAX) {
25404
0
        iattr->state = XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL;
25405
        /*
25406
        * SPEC PSVI Assessment Outcome (Attribute)
25407
        * [validity] = "notKnown"
25408
        * [validation attempted] = "none"
25409
        */
25410
0
    } else {
25411
0
        iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL;
25412
0
    }
25413
0
      }
25414
0
  }
25415
0
    }
25416
25417
0
    if (vctxt->nbAttrInfos == 0)
25418
0
  return (0);
25419
25420
    /*
25421
    * Get the owner element; needed for creation of default attributes.
25422
    * This fixes bug #341337, reported by David Grohmann.
25423
    */
25424
0
    if (vctxt->options & XML_SCHEMA_VAL_VC_I_CREATE) {
25425
0
  xmlSchemaNodeInfoPtr ielem = vctxt->elemInfos[vctxt->depth];
25426
0
  if (ielem && ielem->node && ielem->node->doc)
25427
0
      defAttrOwnerElem = ielem->node;
25428
0
    }
25429
    /*
25430
    * Validate values, create default attributes, evaluate IDCs.
25431
    */
25432
0
    for (i = 0; i < vctxt->nbAttrInfos; i++) {
25433
0
  iattr = vctxt->attrInfos[i];
25434
  /*
25435
  * VAL TODO: Note that we won't try to resolve IDCs to
25436
  * "lax" and "skip" validated attributes. Check what to
25437
  * do in this case.
25438
  */
25439
0
  if ((iattr->state != XML_SCHEMAS_ATTR_ASSESSED) &&
25440
0
      (iattr->state != XML_SCHEMAS_ATTR_DEFAULT))
25441
0
      continue;
25442
  /*
25443
  * VAL TODO: What to do if the type definition is missing?
25444
  */
25445
0
  if (iattr->typeDef == NULL) {
25446
0
      iattr->state = XML_SCHEMAS_ATTR_ERR_NO_TYPE;
25447
0
      continue;
25448
0
  }
25449
25450
0
  ACTIVATE_ATTRIBUTE(iattr);
25451
0
  fixed = 0;
25452
0
  xpathRes = 0;
25453
25454
0
  if (vctxt->xpathStates != NULL) {
25455
      /*
25456
      * Evaluate IDCs.
25457
      */
25458
0
      xpathRes = xmlSchemaXPathEvaluate(vctxt,
25459
0
    XML_ATTRIBUTE_NODE);
25460
0
      if (xpathRes == -1) {
25461
0
    VERROR_INT("xmlSchemaVAttributesComplex",
25462
0
        "calling xmlSchemaXPathEvaluate()");
25463
0
    goto internal_error;
25464
0
      }
25465
0
  }
25466
25467
0
  if (iattr->state == XML_SCHEMAS_ATTR_DEFAULT) {
25468
      /*
25469
      * Default/fixed attributes.
25470
      * We need the value only if we need to resolve IDCs or
25471
      * will create default attributes.
25472
      */
25473
0
      if ((xpathRes) || (defAttrOwnerElem)) {
25474
0
    if (iattr->use->defValue != NULL) {
25475
0
        iattr->value = (xmlChar *) iattr->use->defValue;
25476
0
        iattr->val = iattr->use->defVal;
25477
0
    } else {
25478
0
        iattr->value = (xmlChar *) iattr->decl->defValue;
25479
0
        iattr->val = iattr->decl->defVal;
25480
0
    }
25481
    /*
25482
    * IDCs will consume the precomputed default value,
25483
    * so we need to clone it.
25484
    */
25485
0
    if (iattr->val == NULL) {
25486
0
        VERROR_INT("xmlSchemaVAttributesComplex",
25487
0
      "default/fixed value on an attribute use was "
25488
0
      "not precomputed");
25489
0
        goto internal_error;
25490
0
    }
25491
0
    iattr->val = xmlSchemaCopyValue(iattr->val);
25492
0
    if (iattr->val == NULL) {
25493
0
        VERROR_INT("xmlSchemaVAttributesComplex",
25494
0
      "calling xmlSchemaCopyValue()");
25495
0
        goto internal_error;
25496
0
    }
25497
0
      }
25498
      /*
25499
      * PSVI: Add the default attribute to the current element.
25500
      * VAL TODO: Should we use the *normalized* value? This currently
25501
      *   uses the *initial* value.
25502
      */
25503
25504
0
      if (defAttrOwnerElem) {
25505
0
    xmlChar *normValue;
25506
0
    const xmlChar *value;
25507
25508
0
    value = iattr->value;
25509
    /*
25510
    * Normalize the value.
25511
    */
25512
0
    normValue = xmlSchemaNormalizeValue(iattr->typeDef,
25513
0
        iattr->value);
25514
0
    if (normValue != NULL)
25515
0
        value = BAD_CAST normValue;
25516
25517
0
    if (iattr->nsName == NULL) {
25518
0
        if (xmlNewProp(defAttrOwnerElem,
25519
0
      iattr->localName, value) == NULL) {
25520
0
      VERROR_INT("xmlSchemaVAttributesComplex",
25521
0
          "calling xmlNewProp()");
25522
0
      if (normValue != NULL)
25523
0
          xmlFree(normValue);
25524
0
      goto internal_error;
25525
0
        }
25526
0
    } else {
25527
0
        xmlNsPtr ns;
25528
25529
0
        ns = xmlSearchNsByHref(defAttrOwnerElem->doc,
25530
0
      defAttrOwnerElem, iattr->nsName);
25531
0
        if (ns == NULL) {
25532
0
      xmlChar prefix[13];
25533
0
      int counter = 0;
25534
25535
      /*
25536
      * Create a namespace declaration on the validation
25537
      * root node if no namespace declaration is in scope.
25538
      */
25539
0
      do {
25540
0
          snprintf((char *) prefix, 13, "p%d", counter++);
25541
0
          ns = xmlSearchNs(defAttrOwnerElem->doc,
25542
0
        defAttrOwnerElem, BAD_CAST prefix);
25543
0
          if (counter > 1000) {
25544
0
        VERROR_INT(
25545
0
            "xmlSchemaVAttributesComplex",
25546
0
            "could not compute a ns prefix for a "
25547
0
            "default/fixed attribute");
25548
0
        if (normValue != NULL)
25549
0
            xmlFree(normValue);
25550
0
        goto internal_error;
25551
0
          }
25552
0
      } while (ns != NULL);
25553
0
      ns = xmlNewNs(vctxt->validationRoot,
25554
0
          iattr->nsName, BAD_CAST prefix);
25555
0
        }
25556
        /*
25557
        * TODO:
25558
        * http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0406.html
25559
        * If we have QNames: do we need to ensure there's a
25560
        * prefix defined for the QName?
25561
        */
25562
0
        xmlNewNsProp(defAttrOwnerElem, ns, iattr->localName, value);
25563
0
    }
25564
0
    if (normValue != NULL)
25565
0
        xmlFree(normValue);
25566
0
      }
25567
      /*
25568
      * Go directly to IDC evaluation.
25569
      */
25570
0
      goto eval_idcs;
25571
0
  }
25572
  /*
25573
  * Validate the value.
25574
  */
25575
0
  if (vctxt->value != NULL) {
25576
      /*
25577
      * Free last computed value; just for safety reasons.
25578
      */
25579
0
      xmlSchemaFreeValue(vctxt->value);
25580
0
      vctxt->value = NULL;
25581
0
  }
25582
  /*
25583
  * Note that the attribute *use* can be unavailable, if
25584
  * the attribute was a wild attribute.
25585
  */
25586
0
  if ((iattr->decl->flags & XML_SCHEMAS_ATTR_FIXED) ||
25587
0
      ((iattr->use != NULL) &&
25588
0
       (iattr->use->flags & XML_SCHEMAS_ATTR_FIXED)))
25589
0
      fixed = 1;
25590
0
  else
25591
0
      fixed = 0;
25592
  /*
25593
  * SPEC (cvc-attribute)
25594
  * (3) "The item's `normalized value` must be locally `valid`
25595
  * with respect to that {type definition} as per
25596
  * String Valid ($3.14.4)."
25597
  *
25598
  * VAL TODO: Do we already have the
25599
  * "normalized attribute value" here?
25600
  */
25601
0
  if (xpathRes || fixed) {
25602
0
      iattr->flags |= XML_SCHEMA_NODE_INFO_VALUE_NEEDED;
25603
      /*
25604
      * Request a computed value.
25605
      */
25606
0
      res = xmlSchemaVCheckCVCSimpleType(
25607
0
    ACTXT_CAST vctxt,
25608
0
    iattr->node, iattr->typeDef, iattr->value, &(iattr->val),
25609
0
    1, 1, 0);
25610
0
  } else {
25611
0
      res = xmlSchemaVCheckCVCSimpleType(
25612
0
    ACTXT_CAST vctxt,
25613
0
    iattr->node, iattr->typeDef, iattr->value, NULL,
25614
0
    1, 0, 0);
25615
0
  }
25616
25617
0
  if (res != 0) {
25618
0
      if (res == -1) {
25619
0
    VERROR_INT("xmlSchemaVAttributesComplex",
25620
0
        "calling xmlSchemaStreamValidateSimpleTypeValue()");
25621
0
    goto internal_error;
25622
0
      }
25623
0
      iattr->state = XML_SCHEMAS_ATTR_INVALID_VALUE;
25624
      /*
25625
      * SPEC PSVI Assessment Outcome (Attribute)
25626
      * [validity] = "invalid"
25627
      */
25628
0
      goto eval_idcs;
25629
0
  }
25630
25631
0
  if (fixed) {
25632
      /*
25633
      * SPEC Attribute Locally Valid (Use) (cvc-au)
25634
      * "For an attribute information item to be `valid`
25635
      * with respect to an attribute use its *normalized*
25636
      * value must match the *canonical* lexical
25637
      * representation of the attribute use's {value
25638
      * constraint}value, if it is present and fixed."
25639
      *
25640
      * VAL TODO: The requirement for the *canonical* value
25641
      * will be removed in XML Schema 1.1.
25642
      */
25643
      /*
25644
      * SPEC Attribute Locally Valid (cvc-attribute)
25645
      * (4) "The item's *actual* value must match the *value* of
25646
      * the {value constraint}, if it is present and fixed."
25647
      */
25648
0
      if (iattr->val == NULL) {
25649
    /* VAL TODO: A value was not precomputed. */
25650
0
    goto eval_idcs;
25651
0
      }
25652
0
      if ((iattr->use != NULL) &&
25653
0
    (iattr->use->defValue != NULL)) {
25654
0
    if (iattr->use->defVal == NULL) {
25655
        /* VAL TODO: A default value was not precomputed. */
25656
0
        goto eval_idcs;
25657
0
    }
25658
0
    iattr->vcValue = iattr->use->defValue;
25659
    /*
25660
    if (xmlSchemaCompareValuesWhtsp(attr->val,
25661
        (xmlSchemaWhitespaceValueType) ws,
25662
        attr->use->defVal,
25663
        (xmlSchemaWhitespaceValueType) ws) != 0) {
25664
    */
25665
0
    if (! xmlSchemaAreValuesEqual(iattr->val, iattr->use->defVal))
25666
0
        iattr->state = XML_SCHEMAS_ATTR_ERR_FIXED_VALUE;
25667
0
      } else {
25668
0
    if (iattr->decl->defVal == NULL) {
25669
        /* VAL TODO: A default value was not precomputed. */
25670
0
        goto eval_idcs;
25671
0
    }
25672
0
    iattr->vcValue = iattr->decl->defValue;
25673
    /*
25674
    if (xmlSchemaCompareValuesWhtsp(attr->val,
25675
        (xmlSchemaWhitespaceValueType) ws,
25676
        attrDecl->defVal,
25677
        (xmlSchemaWhitespaceValueType) ws) != 0) {
25678
    */
25679
0
    if (! xmlSchemaAreValuesEqual(iattr->val, iattr->decl->defVal))
25680
0
        iattr->state = XML_SCHEMAS_ATTR_ERR_FIXED_VALUE;
25681
0
      }
25682
      /*
25683
      * [validity] = "valid"
25684
      */
25685
0
  }
25686
0
eval_idcs:
25687
  /*
25688
  * Evaluate IDCs.
25689
  */
25690
0
  if (xpathRes) {
25691
0
      if (xmlSchemaXPathProcessHistory(vctxt,
25692
0
    vctxt->depth +1) == -1) {
25693
0
    VERROR_INT("xmlSchemaVAttributesComplex",
25694
0
        "calling xmlSchemaXPathEvaluate()");
25695
0
    goto internal_error;
25696
0
      }
25697
0
  } else if (vctxt->xpathStates != NULL)
25698
0
      xmlSchemaXPathPop(vctxt);
25699
0
    }
25700
25701
    /*
25702
    * Report errors.
25703
    */
25704
0
    for (i = 0; i < vctxt->nbAttrInfos; i++) {
25705
0
  iattr = vctxt->attrInfos[i];
25706
0
  if ((iattr->state == XML_SCHEMAS_ATTR_META) ||
25707
0
      (iattr->state == XML_SCHEMAS_ATTR_ASSESSED) ||
25708
0
      (iattr->state == XML_SCHEMAS_ATTR_WILD_SKIP) ||
25709
0
      (iattr->state == XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL))
25710
0
      continue;
25711
0
  ACTIVATE_ATTRIBUTE(iattr);
25712
0
  switch (iattr->state) {
25713
0
      case XML_SCHEMAS_ATTR_ERR_MISSING: {
25714
0
        xmlChar *str = NULL;
25715
0
        ACTIVATE_ELEM;
25716
0
        xmlSchemaCustomErr(ACTXT_CAST vctxt,
25717
0
      XML_SCHEMAV_CVC_COMPLEX_TYPE_4, NULL, NULL,
25718
0
      "The attribute '%s' is required but missing",
25719
0
      xmlSchemaFormatQName(&str,
25720
0
          iattr->decl->targetNamespace,
25721
0
          iattr->decl->name),
25722
0
      NULL);
25723
0
        FREE_AND_NULL(str)
25724
0
        break;
25725
0
    }
25726
0
      case XML_SCHEMAS_ATTR_ERR_NO_TYPE:
25727
0
    VERROR(XML_SCHEMAV_CVC_ATTRIBUTE_2, NULL,
25728
0
        "The type definition is absent");
25729
0
    break;
25730
0
      case XML_SCHEMAS_ATTR_ERR_FIXED_VALUE:
25731
0
    xmlSchemaCustomErr(ACTXT_CAST vctxt,
25732
0
        XML_SCHEMAV_CVC_AU, NULL, NULL,
25733
0
        "The value '%s' does not match the fixed "
25734
0
        "value constraint '%s'",
25735
0
        iattr->value, iattr->vcValue);
25736
0
    break;
25737
0
      case XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL:
25738
0
    VERROR(XML_SCHEMAV_CVC_WILDCARD, NULL,
25739
0
        "No matching global attribute declaration available, but "
25740
0
        "demanded by the strict wildcard");
25741
0
    break;
25742
0
      case XML_SCHEMAS_ATTR_UNKNOWN:
25743
0
    if (iattr->metaType)
25744
0
        break;
25745
    /*
25746
    * MAYBE VAL TODO: One might report different error messages
25747
    * for the following errors.
25748
    */
25749
0
    if (type->attributeWildcard == NULL) {
25750
0
        xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt,
25751
0
      XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_1, iattr, NULL);
25752
0
    } else {
25753
0
        xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt,
25754
0
      XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_2, iattr, NULL);
25755
0
    }
25756
0
    break;
25757
0
      default:
25758
0
    break;
25759
0
  }
25760
0
    }
25761
25762
0
    ACTIVATE_ELEM;
25763
0
    return (0);
25764
0
internal_error:
25765
0
    ACTIVATE_ELEM;
25766
0
    return (-1);
25767
0
}
25768
25769
static int
25770
xmlSchemaValidateElemWildcard(xmlSchemaValidCtxtPtr vctxt,
25771
            int *skip)
25772
0
{
25773
0
    xmlSchemaWildcardPtr wild = (xmlSchemaWildcardPtr) vctxt->inode->decl;
25774
    /*
25775
    * The namespace of the element was already identified to be
25776
    * matching the wildcard.
25777
    */
25778
0
    if ((skip == NULL) || (wild == NULL) ||
25779
0
  (wild->type != XML_SCHEMA_TYPE_ANY)) {
25780
0
  VERROR_INT("xmlSchemaValidateElemWildcard",
25781
0
      "bad arguments");
25782
0
  return (-1);
25783
0
    }
25784
0
    *skip = 0;
25785
0
    if (wild->processContents == XML_SCHEMAS_ANY_SKIP) {
25786
  /*
25787
  * URGENT VAL TODO: Either we need to position the stream to the
25788
  * next sibling, or walk the whole subtree.
25789
  */
25790
0
  *skip = 1;
25791
0
  return (0);
25792
0
    }
25793
0
    {
25794
0
  xmlSchemaElementPtr decl = NULL;
25795
25796
0
  decl = xmlSchemaGetElem(vctxt->schema,
25797
0
      vctxt->inode->localName, vctxt->inode->nsName);
25798
0
  if (decl != NULL) {
25799
0
      vctxt->inode->decl = decl;
25800
0
      return (0);
25801
0
  }
25802
0
    }
25803
0
    if (wild->processContents == XML_SCHEMAS_ANY_STRICT) {
25804
  /* VAL TODO: Change to proper error code. */
25805
0
  VERROR(XML_SCHEMAV_CVC_ELT_1, NULL, /* WXS_BASIC_CAST wild */
25806
0
      "No matching global element declaration available, but "
25807
0
      "demanded by the strict wildcard");
25808
0
  return (vctxt->err);
25809
0
    }
25810
0
    if (vctxt->nbAttrInfos != 0) {
25811
0
  xmlSchemaAttrInfoPtr iattr;
25812
  /*
25813
  * SPEC Validation Rule: Schema-Validity Assessment (Element)
25814
  * (1.2.1.2.1) - (1.2.1.2.3 )
25815
  *
25816
  * Use the xsi:type attribute for the type definition.
25817
  */
25818
0
  iattr = xmlSchemaGetMetaAttrInfo(vctxt,
25819
0
      XML_SCHEMA_ATTR_INFO_META_XSI_TYPE);
25820
0
  if (iattr != NULL) {
25821
0
      if (xmlSchemaProcessXSIType(vctxt, iattr,
25822
0
    &(vctxt->inode->typeDef), NULL) == -1) {
25823
0
    VERROR_INT("xmlSchemaValidateElemWildcard",
25824
0
        "calling xmlSchemaProcessXSIType() to "
25825
0
        "process the attribute 'xsi:nil'");
25826
0
    return (-1);
25827
0
      }
25828
      /*
25829
      * Don't return an error on purpose.
25830
      */
25831
0
      return (0);
25832
0
  }
25833
0
    }
25834
    /*
25835
    * SPEC Validation Rule: Schema-Validity Assessment (Element)
25836
    *
25837
    * Fallback to "anyType".
25838
    */
25839
0
    vctxt->inode->typeDef =
25840
0
  xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
25841
0
    return (0);
25842
0
}
25843
25844
/*
25845
* xmlSchemaCheckCOSValidDefault:
25846
*
25847
* This will be called if: not nilled, no content and a default/fixed
25848
* value is provided.
25849
*/
25850
25851
static int
25852
xmlSchemaCheckCOSValidDefault(xmlSchemaValidCtxtPtr vctxt,
25853
            const xmlChar *value,
25854
            xmlSchemaValPtr *val)
25855
0
{
25856
0
    int ret = 0;
25857
0
    xmlSchemaNodeInfoPtr inode = vctxt->inode;
25858
25859
    /*
25860
    * cos-valid-default:
25861
    * Schema Component Constraint: Element Default Valid (Immediate)
25862
    * For a string to be a valid default with respect to a type
25863
    * definition the appropriate case among the following must be true:
25864
    */
25865
0
    if WXS_IS_COMPLEX(inode->typeDef) {
25866
  /*
25867
  * Complex type.
25868
  *
25869
  * SPEC (2.1) "its {content type} must be a simple type definition
25870
  * or mixed."
25871
  * SPEC (2.2.2) "If the {content type} is mixed, then the {content
25872
  * type}'s particle must be `emptiable` as defined by
25873
  * Particle Emptiable ($3.9.6)."
25874
  */
25875
0
  if ((! WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) &&
25876
0
      ((! WXS_HAS_MIXED_CONTENT(inode->typeDef)) ||
25877
0
       (! WXS_EMPTIABLE(inode->typeDef)))) {
25878
0
      ret = XML_SCHEMAP_COS_VALID_DEFAULT_2_1;
25879
      /* NOTE that this covers (2.2.2) as well. */
25880
0
      VERROR(ret, NULL,
25881
0
    "For a string to be a valid default, the type definition "
25882
0
    "must be a simple type or a complex type with simple content "
25883
0
    "or mixed content and a particle emptiable");
25884
0
      return(ret);
25885
0
  }
25886
0
    }
25887
    /*
25888
    * 1 If the type definition is a simple type definition, then the string
25889
    * must be `valid` with respect to that definition as defined by String
25890
    * Valid ($3.14.4).
25891
    *
25892
    * AND
25893
    *
25894
    * 2.2.1 If the {content type} is a simple type definition, then the
25895
    * string must be `valid` with respect to that simple type definition
25896
    * as defined by String Valid ($3.14.4).
25897
    */
25898
0
    if (WXS_IS_SIMPLE(inode->typeDef)) {
25899
25900
0
  ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST vctxt,
25901
0
      NULL, inode->typeDef, value, val, 1, 1, 0);
25902
25903
0
    } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
25904
25905
0
  ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST vctxt,
25906
0
      NULL, inode->typeDef->contentTypeDef, value, val, 1, 1, 0);
25907
0
    }
25908
0
    if (ret < 0) {
25909
0
  VERROR_INT("xmlSchemaCheckCOSValidDefault",
25910
0
      "calling xmlSchemaVCheckCVCSimpleType()");
25911
0
    }
25912
0
    return (ret);
25913
0
}
25914
25915
static void
25916
xmlSchemaVContentModelCallback(xmlRegExecCtxtPtr exec ATTRIBUTE_UNUSED,
25917
             const xmlChar * name ATTRIBUTE_UNUSED,
25918
             void *transdata, void *inputdata)
25919
0
{
25920
0
    xmlSchemaElementPtr item = (xmlSchemaElementPtr) transdata;
25921
0
    xmlSchemaNodeInfoPtr inode = (xmlSchemaNodeInfoPtr) inputdata;
25922
0
    inode->decl = item;
25923
0
}
25924
25925
static int
25926
xmlSchemaValidatorPushElem(xmlSchemaValidCtxtPtr vctxt)
25927
0
{
25928
0
    vctxt->inode = xmlSchemaGetFreshElemInfo(vctxt);
25929
0
    if (vctxt->inode == NULL) {
25930
0
  VERROR_INT("xmlSchemaValidatorPushElem",
25931
0
      "calling xmlSchemaGetFreshElemInfo()");
25932
0
  return (-1);
25933
0
    }
25934
0
    vctxt->nbAttrInfos = 0;
25935
0
    return (0);
25936
0
}
25937
25938
static int
25939
xmlSchemaVCheckINodeDataType(xmlSchemaValidCtxtPtr vctxt,
25940
           xmlSchemaNodeInfoPtr inode,
25941
           xmlSchemaTypePtr type,
25942
           const xmlChar *value)
25943
0
{
25944
0
    if (inode->flags & XML_SCHEMA_NODE_INFO_VALUE_NEEDED)
25945
0
  return (xmlSchemaVCheckCVCSimpleType(
25946
0
      ACTXT_CAST vctxt, NULL,
25947
0
      type, value, &(inode->val), 1, 1, 0));
25948
0
    else
25949
0
  return (xmlSchemaVCheckCVCSimpleType(
25950
0
      ACTXT_CAST vctxt, NULL,
25951
0
      type, value, NULL, 1, 0, 0));
25952
0
}
25953
25954
25955
25956
/*
25957
* Process END of element.
25958
*/
25959
static int
25960
xmlSchemaValidatorPopElem(xmlSchemaValidCtxtPtr vctxt)
25961
0
{
25962
0
    int ret = 0;
25963
0
    xmlSchemaNodeInfoPtr inode = vctxt->inode;
25964
25965
0
    if (vctxt->nbAttrInfos != 0)
25966
0
  xmlSchemaClearAttrInfos(vctxt);
25967
0
    if (inode->flags & XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED) {
25968
  /*
25969
  * This element was not expected;
25970
  * we will not validate child elements of broken parents.
25971
  * Skip validation of all content of the parent.
25972
  */
25973
0
  vctxt->skipDepth = vctxt->depth -1;
25974
0
  goto end_elem;
25975
0
    }
25976
0
    if ((inode->typeDef == NULL) ||
25977
0
  (inode->flags & XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE)) {
25978
  /*
25979
  * 1. the type definition might be missing if the element was
25980
  *    error prone
25981
  * 2. it might be abstract.
25982
  */
25983
0
  goto end_elem;
25984
0
    }
25985
    /*
25986
    * Check the content model.
25987
    */
25988
0
    if ((inode->typeDef->contentType == XML_SCHEMA_CONTENT_MIXED) ||
25989
0
  (inode->typeDef->contentType == XML_SCHEMA_CONTENT_ELEMENTS)) {
25990
25991
  /*
25992
  * Workaround for "anyType".
25993
  */
25994
0
  if (inode->typeDef->builtInType == XML_SCHEMAS_ANYTYPE)
25995
0
      goto character_content;
25996
25997
0
  if ((inode->flags & XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT) == 0) {
25998
0
      xmlChar *values[10];
25999
0
      int terminal, nbval = 10, nbneg;
26000
26001
0
      if (inode->regexCtxt == NULL) {
26002
    /*
26003
    * Create the regex context.
26004
    */
26005
0
    inode->regexCtxt =
26006
0
        xmlRegNewExecCtxt(inode->typeDef->contModel,
26007
0
        xmlSchemaVContentModelCallback, vctxt);
26008
0
    if (inode->regexCtxt == NULL) {
26009
0
        VERROR_INT("xmlSchemaValidatorPopElem",
26010
0
      "failed to create a regex context");
26011
0
        goto internal_error;
26012
0
    }
26013
0
      }
26014
26015
      /*
26016
       * Do not check further content if the node has been nilled
26017
       */
26018
0
      if (INODE_NILLED(inode)) {
26019
0
    ret = 0;
26020
0
                goto skip_nilled;
26021
0
      }
26022
26023
      /*
26024
      * Get hold of the still expected content, since a further
26025
      * call to xmlRegExecPushString() will lose this information.
26026
      */
26027
0
      xmlRegExecNextValues(inode->regexCtxt,
26028
0
    &nbval, &nbneg, &values[0], &terminal);
26029
0
      ret = xmlRegExecPushString(inode->regexCtxt, NULL, NULL);
26030
0
      if ((ret<0) || ((ret==0) && (!INODE_NILLED(inode)))) {
26031
    /*
26032
    * Still missing something.
26033
    */
26034
0
    ret = 1;
26035
0
    inode->flags |=
26036
0
        XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT;
26037
0
    xmlSchemaComplexTypeErr(ACTXT_CAST vctxt,
26038
0
        XML_SCHEMAV_ELEMENT_CONTENT, NULL, NULL,
26039
0
        "Missing child element(s)",
26040
0
        nbval, nbneg, values);
26041
0
      } else {
26042
    /*
26043
    * Content model is satisfied.
26044
    */
26045
0
    ret = 0;
26046
0
      }
26047
26048
0
  }
26049
0
    }
26050
26051
0
skip_nilled:
26052
26053
0
    if (inode->typeDef->contentType == XML_SCHEMA_CONTENT_ELEMENTS)
26054
0
  goto end_elem;
26055
26056
0
character_content:
26057
26058
0
    if (vctxt->value != NULL) {
26059
0
  xmlSchemaFreeValue(vctxt->value);
26060
0
  vctxt->value = NULL;
26061
0
    }
26062
    /*
26063
    * Check character content.
26064
    */
26065
0
    if (inode->decl == NULL) {
26066
  /*
26067
  * Speedup if no declaration exists.
26068
  */
26069
0
  if (WXS_IS_SIMPLE(inode->typeDef)) {
26070
0
      ret = xmlSchemaVCheckINodeDataType(vctxt,
26071
0
    inode, inode->typeDef, inode->value);
26072
0
  } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
26073
0
      ret = xmlSchemaVCheckINodeDataType(vctxt,
26074
0
    inode, inode->typeDef->contentTypeDef,
26075
0
    inode->value);
26076
0
  }
26077
0
  if (ret < 0) {
26078
0
      VERROR_INT("xmlSchemaValidatorPopElem",
26079
0
    "calling xmlSchemaVCheckCVCSimpleType()");
26080
0
      goto internal_error;
26081
0
  }
26082
0
  goto end_elem;
26083
0
    }
26084
    /*
26085
    * cvc-elt (3.3.4) : 5
26086
    * The appropriate case among the following must be true:
26087
    */
26088
    /*
26089
    * cvc-elt (3.3.4) : 5.1
26090
    * If the declaration has a {value constraint},
26091
    * the item has neither element nor character [children] and
26092
    * clause 3.2 has not applied, then all of the following must be true:
26093
    */
26094
0
    if ((inode->decl->value != NULL) &&
26095
0
  (inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY) &&
26096
0
  (! INODE_NILLED(inode))) {
26097
  /*
26098
  * cvc-elt (3.3.4) : 5.1.1
26099
  * If the `actual type definition` is a `local type definition`
26100
  * then the canonical lexical representation of the {value constraint}
26101
  * value must be a valid default for the `actual type definition` as
26102
  * defined in Element Default Valid (Immediate) ($3.3.6).
26103
  */
26104
  /*
26105
  * NOTE: 'local' above means types acquired by xsi:type.
26106
  * NOTE: Although the *canonical* value is stated, it is not
26107
  * relevant if canonical or not. Additionally XML Schema 1.1
26108
  * will removed this requirement as well.
26109
  */
26110
0
  if (inode->flags & XML_SCHEMA_ELEM_INFO_LOCAL_TYPE) {
26111
26112
0
      ret = xmlSchemaCheckCOSValidDefault(vctxt,
26113
0
    inode->decl->value, &(inode->val));
26114
0
      if (ret != 0) {
26115
0
    if (ret < 0) {
26116
0
        VERROR_INT("xmlSchemaValidatorPopElem",
26117
0
      "calling xmlSchemaCheckCOSValidDefault()");
26118
0
        goto internal_error;
26119
0
    }
26120
0
    goto end_elem;
26121
0
      }
26122
      /*
26123
      * Stop here, to avoid redundant validation of the value
26124
      * (see following).
26125
      */
26126
0
      goto default_psvi;
26127
0
  }
26128
  /*
26129
  * cvc-elt (3.3.4) : 5.1.2
26130
  * The element information item with the canonical lexical
26131
  * representation of the {value constraint} value used as its
26132
  * `normalized value` must be `valid` with respect to the
26133
  * `actual type definition` as defined by Element Locally Valid (Type)
26134
  * ($3.3.4).
26135
  */
26136
0
  if (WXS_IS_SIMPLE(inode->typeDef)) {
26137
0
      ret = xmlSchemaVCheckINodeDataType(vctxt,
26138
0
    inode, inode->typeDef, inode->decl->value);
26139
0
  } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
26140
0
      ret = xmlSchemaVCheckINodeDataType(vctxt,
26141
0
    inode, inode->typeDef->contentTypeDef,
26142
0
    inode->decl->value);
26143
0
  }
26144
0
  if (ret != 0) {
26145
0
      if (ret < 0) {
26146
0
    VERROR_INT("xmlSchemaValidatorPopElem",
26147
0
        "calling xmlSchemaVCheckCVCSimpleType()");
26148
0
    goto internal_error;
26149
0
      }
26150
0
      goto end_elem;
26151
0
  }
26152
26153
0
default_psvi:
26154
  /*
26155
  * PSVI: Create a text node on the instance element.
26156
  */
26157
0
  if ((vctxt->options & XML_SCHEMA_VAL_VC_I_CREATE) &&
26158
0
      (inode->node != NULL)) {
26159
0
      xmlNodePtr textChild;
26160
0
      xmlChar *normValue;
26161
      /*
26162
      * VAL TODO: Normalize the value.
26163
      */
26164
0
      normValue = xmlSchemaNormalizeValue(inode->typeDef,
26165
0
    inode->decl->value);
26166
0
      if (normValue != NULL) {
26167
0
    textChild = xmlNewDocText(inode->node->doc,
26168
0
                        BAD_CAST normValue);
26169
0
    xmlFree(normValue);
26170
0
      } else
26171
0
    textChild = xmlNewDocText(inode->node->doc,
26172
0
                        inode->decl->value);
26173
0
      if (textChild == NULL) {
26174
0
    VERROR_INT("xmlSchemaValidatorPopElem",
26175
0
        "calling xmlNewDocText()");
26176
0
    goto internal_error;
26177
0
      } else
26178
0
    xmlAddChild(inode->node, textChild);
26179
0
  }
26180
26181
0
    } else if (! INODE_NILLED(inode)) {
26182
  /*
26183
  * 5.2.1 The element information item must be `valid` with respect
26184
  * to the `actual type definition` as defined by Element Locally
26185
  * Valid (Type) ($3.3.4).
26186
  */
26187
0
  if (WXS_IS_SIMPLE(inode->typeDef)) {
26188
       /*
26189
      * SPEC (cvc-type) (3.1)
26190
      * "If the type definition is a simple type definition, ..."
26191
      * (3.1.3) "If clause 3.2 of Element Locally Valid
26192
      * (Element) ($3.3.4) did not apply, then the `normalized value`
26193
      * must be `valid` with respect to the type definition as defined
26194
      * by String Valid ($3.14.4).
26195
      */
26196
0
      ret = xmlSchemaVCheckINodeDataType(vctxt,
26197
0
        inode, inode->typeDef, inode->value);
26198
0
  } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
26199
      /*
26200
      * SPEC (cvc-type) (3.2) "If the type definition is a complex type
26201
      * definition, then the element information item must be
26202
      * `valid` with respect to the type definition as per
26203
      * Element Locally Valid (Complex Type) ($3.4.4);"
26204
      *
26205
      * SPEC (cvc-complex-type) (2.2)
26206
      * "If the {content type} is a simple type definition, ...
26207
      * the `normalized value` of the element information item is
26208
      * `valid` with respect to that simple type definition as
26209
      * defined by String Valid ($3.14.4)."
26210
      */
26211
0
      ret = xmlSchemaVCheckINodeDataType(vctxt,
26212
0
    inode, inode->typeDef->contentTypeDef, inode->value);
26213
0
  }
26214
0
  if (ret != 0) {
26215
0
      if (ret < 0) {
26216
0
    VERROR_INT("xmlSchemaValidatorPopElem",
26217
0
        "calling xmlSchemaVCheckCVCSimpleType()");
26218
0
    goto internal_error;
26219
0
      }
26220
0
      goto end_elem;
26221
0
  }
26222
  /*
26223
  * 5.2.2 If there is a fixed {value constraint} and clause 3.2 has
26224
  * not applied, all of the following must be true:
26225
  */
26226
0
  if ((inode->decl->value != NULL) &&
26227
0
      (inode->decl->flags & XML_SCHEMAS_ELEM_FIXED)) {
26228
26229
      /*
26230
      * TODO: We will need a computed value, when comparison is
26231
      * done on computed values.
26232
      */
26233
      /*
26234
      * 5.2.2.1 The element information item must have no element
26235
      * information item [children].
26236
      */
26237
0
      if (inode->flags &
26238
0
        XML_SCHEMA_ELEM_INFO_HAS_ELEM_CONTENT) {
26239
0
    ret = XML_SCHEMAV_CVC_ELT_5_2_2_1;
26240
0
    VERROR(ret, NULL,
26241
0
        "The content must not contain element nodes since "
26242
0
        "there is a fixed value constraint");
26243
0
    goto end_elem;
26244
0
      } else {
26245
    /*
26246
    * 5.2.2.2 The appropriate case among the following must
26247
    * be true:
26248
    */
26249
0
    if (WXS_HAS_MIXED_CONTENT(inode->typeDef)) {
26250
        /*
26251
        * 5.2.2.2.1 If the {content type} of the `actual type
26252
        * definition` is mixed, then the *initial value* of the
26253
        * item must match the canonical lexical representation
26254
        * of the {value constraint} value.
26255
        *
26256
        * ... the *initial value* of an element information
26257
        * item is the string composed of, in order, the
26258
        * [character code] of each character information item in
26259
        * the [children] of that element information item.
26260
        */
26261
0
        if (! xmlStrEqual(inode->value, inode->decl->value)){
26262
      /*
26263
      * VAL TODO: Report invalid & expected values as well.
26264
      * VAL TODO: Implement the canonical stuff.
26265
      */
26266
0
      ret = XML_SCHEMAV_CVC_ELT_5_2_2_2_1;
26267
0
      xmlSchemaCustomErr(ACTXT_CAST vctxt,
26268
0
          ret, NULL, NULL,
26269
0
          "The initial value '%s' does not match the fixed "
26270
0
          "value constraint '%s'",
26271
0
          inode->value, inode->decl->value);
26272
0
      goto end_elem;
26273
0
        }
26274
0
    } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
26275
        /*
26276
        * 5.2.2.2.2 If the {content type} of the `actual type
26277
        * definition` is a simple type definition, then the
26278
        * *actual value* of the item must match the canonical
26279
        * lexical representation of the {value constraint} value.
26280
        */
26281
        /*
26282
        * VAL TODO: *actual value* is the normalized value, impl.
26283
        *           this.
26284
        * VAL TODO: Report invalid & expected values as well.
26285
        * VAL TODO: Implement a comparison with the computed values.
26286
        */
26287
0
        if (! xmlStrEqual(inode->value,
26288
0
          inode->decl->value)) {
26289
0
      ret = XML_SCHEMAV_CVC_ELT_5_2_2_2_2;
26290
0
      xmlSchemaCustomErr(ACTXT_CAST vctxt,
26291
0
          ret, NULL, NULL,
26292
0
          "The actual value '%s' does not match the fixed "
26293
0
          "value constraint '%s'",
26294
0
          inode->value,
26295
0
          inode->decl->value);
26296
0
      goto end_elem;
26297
0
        }
26298
0
    }
26299
0
      }
26300
0
  }
26301
0
    }
26302
26303
0
end_elem:
26304
0
    if (vctxt->depth < 0) {
26305
  /* TODO: raise error? */
26306
0
  return (0);
26307
0
    }
26308
0
    if (vctxt->depth == vctxt->skipDepth)
26309
0
  vctxt->skipDepth = -1;
26310
    /*
26311
    * Evaluate the history of XPath state objects.
26312
    */
26313
0
    if (inode->appliedXPath &&
26314
0
  (xmlSchemaXPathProcessHistory(vctxt, vctxt->depth) == -1))
26315
0
  goto internal_error;
26316
    /*
26317
    * MAYBE TODO:
26318
    * SPEC (6) "The element information item must be `valid` with
26319
    * respect to each of the {identity-constraint definitions} as per
26320
    * Identity-constraint Satisfied ($3.11.4)."
26321
    */
26322
    /*
26323
    * PSVI TODO: If we expose IDC node-tables via PSVI then the tables
26324
    *   need to be built in any case.
26325
    *   We will currently build IDC node-tables and bubble them only if
26326
    *   keyrefs do exist.
26327
    */
26328
26329
    /*
26330
    * Add the current IDC target-nodes to the IDC node-tables.
26331
    */
26332
0
    if ((inode->idcMatchers != NULL) &&
26333
0
  (vctxt->hasKeyrefs || vctxt->createIDCNodeTables))
26334
0
    {
26335
0
  if (xmlSchemaIDCFillNodeTables(vctxt, inode) == -1)
26336
0
      goto internal_error;
26337
0
    }
26338
    /*
26339
    * Validate IDC keyrefs.
26340
    */
26341
0
    if (vctxt->inode->hasKeyrefs)
26342
0
  if (xmlSchemaCheckCVCIDCKeyRef(vctxt) == -1)
26343
0
      goto internal_error;
26344
    /*
26345
    * Merge/free the IDC table.
26346
    */
26347
0
    if (inode->idcTable != NULL) {
26348
0
  if ((vctxt->depth > 0) &&
26349
0
      (vctxt->hasKeyrefs || vctxt->createIDCNodeTables))
26350
0
  {
26351
      /*
26352
      * Merge the IDC node table with the table of the parent node.
26353
      */
26354
0
      if (xmlSchemaBubbleIDCNodeTables(vctxt) == -1)
26355
0
    goto internal_error;
26356
0
  }
26357
0
    }
26358
    /*
26359
    * Clear the current ielem.
26360
    * VAL TODO: Don't free the PSVI IDC tables if they are
26361
    * requested for the PSVI.
26362
    */
26363
0
    xmlSchemaClearElemInfo(vctxt, inode);
26364
    /*
26365
    * Skip further processing if we are on the validation root.
26366
    */
26367
0
    if (vctxt->depth == 0) {
26368
0
  vctxt->depth--;
26369
0
  vctxt->inode = NULL;
26370
0
  return (0);
26371
0
    }
26372
    /*
26373
    * Reset the keyrefDepth if needed.
26374
    */
26375
0
    if (vctxt->aidcs != NULL) {
26376
0
  xmlSchemaIDCAugPtr aidc = vctxt->aidcs;
26377
0
  do {
26378
0
      if (aidc->keyrefDepth == vctxt->depth) {
26379
    /*
26380
    * A 'keyrefDepth' of a key/unique IDC matches the current
26381
    * depth, this means that we are leaving the scope of the
26382
    * top-most keyref IDC which refers to this IDC.
26383
    */
26384
0
    aidc->keyrefDepth = -1;
26385
0
      }
26386
0
      aidc = aidc->next;
26387
0
  } while (aidc != NULL);
26388
0
    }
26389
0
    vctxt->depth--;
26390
0
    vctxt->inode = vctxt->elemInfos[vctxt->depth];
26391
    /*
26392
    * VAL TODO: 7 If the element information item is the `validation root`, it must be
26393
    * `valid` per Validation Root Valid (ID/IDREF) ($3.3.4).
26394
    */
26395
0
    return (ret);
26396
26397
0
internal_error:
26398
0
    vctxt->err = -1;
26399
0
    return (-1);
26400
0
}
26401
26402
/*
26403
* 3.4.4 Complex Type Definition Validation Rules
26404
* Validation Rule: Element Locally Valid (Complex Type) (cvc-complex-type)
26405
*/
26406
static int
26407
xmlSchemaValidateChildElem(xmlSchemaValidCtxtPtr vctxt)
26408
0
{
26409
0
    xmlSchemaNodeInfoPtr pielem;
26410
0
    xmlSchemaTypePtr ptype;
26411
0
    int ret = 0;
26412
26413
0
    if (vctxt->depth <= 0) {
26414
0
  VERROR_INT("xmlSchemaValidateChildElem",
26415
0
      "not intended for the validation root");
26416
0
  return (-1);
26417
0
    }
26418
0
    pielem = vctxt->elemInfos[vctxt->depth -1];
26419
0
    if (pielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
26420
0
  pielem->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
26421
    /*
26422
    * Handle 'nilled' elements.
26423
    */
26424
0
    if (INODE_NILLED(pielem)) {
26425
  /*
26426
  * SPEC (cvc-elt) (3.3.4) : (3.2.1)
26427
  */
26428
0
  ACTIVATE_PARENT_ELEM;
26429
0
  ret = XML_SCHEMAV_CVC_ELT_3_2_1;
26430
0
  VERROR(ret, NULL,
26431
0
      "Neither character nor element content is allowed, "
26432
0
      "because the element was 'nilled'");
26433
0
  ACTIVATE_ELEM;
26434
0
  goto unexpected_elem;
26435
0
    }
26436
26437
0
    ptype = pielem->typeDef;
26438
26439
0
    if (ptype->builtInType == XML_SCHEMAS_ANYTYPE) {
26440
  /*
26441
  * Workaround for "anyType": we have currently no content model
26442
  * assigned for "anyType", so handle it explicitly.
26443
  * "anyType" has an unbounded, lax "any" wildcard.
26444
  */
26445
0
  vctxt->inode->decl = xmlSchemaGetElem(vctxt->schema,
26446
0
      vctxt->inode->localName,
26447
0
      vctxt->inode->nsName);
26448
26449
0
  if (vctxt->inode->decl == NULL) {
26450
0
      xmlSchemaAttrInfoPtr iattr;
26451
      /*
26452
      * Process "xsi:type".
26453
      * SPEC (cvc-assess-elt) (1.2.1.2.1) - (1.2.1.2.3)
26454
      */
26455
0
      iattr = xmlSchemaGetMetaAttrInfo(vctxt,
26456
0
    XML_SCHEMA_ATTR_INFO_META_XSI_TYPE);
26457
0
      if (iattr != NULL) {
26458
0
    ret = xmlSchemaProcessXSIType(vctxt, iattr,
26459
0
        &(vctxt->inode->typeDef), NULL);
26460
0
    if (ret != 0) {
26461
0
        if (ret == -1) {
26462
0
      VERROR_INT("xmlSchemaValidateChildElem",
26463
0
          "calling xmlSchemaProcessXSIType() to "
26464
0
          "process the attribute 'xsi:nil'");
26465
0
      return (-1);
26466
0
        }
26467
0
        return (ret);
26468
0
    }
26469
0
      } else {
26470
     /*
26471
     * Fallback to "anyType".
26472
     *
26473
     * SPEC (cvc-assess-elt)
26474
     * "If the item cannot be `strictly assessed`, [...]
26475
     * an element information item's schema validity may be laxly
26476
     * assessed if its `context-determined declaration` is not
26477
     * skip by `validating` with respect to the `ur-type
26478
     * definition` as per Element Locally Valid (Type) ($3.3.4)."
26479
    */
26480
0
    vctxt->inode->typeDef =
26481
0
        xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
26482
0
      }
26483
0
  }
26484
0
  return (0);
26485
0
    }
26486
26487
0
    switch (ptype->contentType) {
26488
0
  case XML_SCHEMA_CONTENT_EMPTY:
26489
      /*
26490
      * SPEC (2.1) "If the {content type} is empty, then the
26491
      * element information item has no character or element
26492
      * information item [children]."
26493
      */
26494
0
      ACTIVATE_PARENT_ELEM
26495
0
      ret = XML_SCHEMAV_CVC_COMPLEX_TYPE_2_1;
26496
0
      VERROR(ret, NULL,
26497
0
    "Element content is not allowed, "
26498
0
    "because the content type is empty");
26499
0
      ACTIVATE_ELEM
26500
0
      goto unexpected_elem;
26501
0
      break;
26502
26503
0
  case XML_SCHEMA_CONTENT_MIXED:
26504
0
        case XML_SCHEMA_CONTENT_ELEMENTS: {
26505
0
      xmlRegExecCtxtPtr regexCtxt;
26506
0
      xmlChar *values[10];
26507
0
      int terminal, nbval = 10, nbneg;
26508
26509
      /* VAL TODO: Optimized "anyType" validation.*/
26510
26511
0
      if (ptype->contModel == NULL) {
26512
0
    VERROR_INT("xmlSchemaValidateChildElem",
26513
0
        "type has elem content but no content model");
26514
0
    return (-1);
26515
0
      }
26516
      /*
26517
      * Safety belt for evaluation if the cont. model was already
26518
      * examined to be invalid.
26519
      */
26520
0
      if (pielem->flags & XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT) {
26521
0
    VERROR_INT("xmlSchemaValidateChildElem",
26522
0
        "validating elem, but elem content is already invalid");
26523
0
    return (-1);
26524
0
      }
26525
26526
0
      regexCtxt = pielem->regexCtxt;
26527
0
      if (regexCtxt == NULL) {
26528
    /*
26529
    * Create the regex context.
26530
    */
26531
0
    regexCtxt = xmlRegNewExecCtxt(ptype->contModel,
26532
0
        xmlSchemaVContentModelCallback, vctxt);
26533
0
    if (regexCtxt == NULL) {
26534
0
        VERROR_INT("xmlSchemaValidateChildElem",
26535
0
      "failed to create a regex context");
26536
0
        return (-1);
26537
0
    }
26538
0
    pielem->regexCtxt = regexCtxt;
26539
0
      }
26540
26541
      /*
26542
      * SPEC (2.4) "If the {content type} is element-only or mixed,
26543
      * then the sequence of the element information item's
26544
      * element information item [children], if any, taken in
26545
      * order, is `valid` with respect to the {content type}'s
26546
      * particle, as defined in Element Sequence Locally Valid
26547
      * (Particle) ($3.9.4)."
26548
      */
26549
0
      ret = xmlRegExecPushString2(regexCtxt,
26550
0
    vctxt->inode->localName,
26551
0
    vctxt->inode->nsName,
26552
0
    vctxt->inode);
26553
0
      if (vctxt->err == XML_SCHEMAV_INTERNAL) {
26554
0
    VERROR_INT("xmlSchemaValidateChildElem",
26555
0
        "calling xmlRegExecPushString2()");
26556
0
    return (-1);
26557
0
      }
26558
0
      if (ret < 0) {
26559
0
    xmlRegExecErrInfo(regexCtxt, NULL, &nbval, &nbneg,
26560
0
        &values[0], &terminal);
26561
0
    xmlSchemaComplexTypeErr(ACTXT_CAST vctxt,
26562
0
        XML_SCHEMAV_ELEMENT_CONTENT, NULL,NULL,
26563
0
        "This element is not expected",
26564
0
        nbval, nbneg, values);
26565
0
    ret = vctxt->err;
26566
0
    goto unexpected_elem;
26567
0
      } else
26568
0
    ret = 0;
26569
0
  }
26570
0
      break;
26571
0
  case XML_SCHEMA_CONTENT_SIMPLE:
26572
0
  case XML_SCHEMA_CONTENT_BASIC:
26573
0
      ACTIVATE_PARENT_ELEM
26574
0
      if (WXS_IS_COMPLEX(ptype)) {
26575
    /*
26576
    * SPEC (cvc-complex-type) (2.2)
26577
    * "If the {content type} is a simple type definition, then
26578
    * the element information item has no element information
26579
    * item [children], ..."
26580
    */
26581
0
    ret = XML_SCHEMAV_CVC_COMPLEX_TYPE_2_2;
26582
0
    VERROR(ret, NULL, "Element content is not allowed, "
26583
0
        "because the content type is a simple type definition");
26584
0
      } else {
26585
    /*
26586
    * SPEC (cvc-type) (3.1.2) "The element information item must
26587
    * have no element information item [children]."
26588
    */
26589
0
    ret = XML_SCHEMAV_CVC_TYPE_3_1_2;
26590
0
    VERROR(ret, NULL, "Element content is not allowed, "
26591
0
        "because the type definition is simple");
26592
0
      }
26593
0
      ACTIVATE_ELEM
26594
0
      ret = vctxt->err;
26595
0
      goto unexpected_elem;
26596
0
      break;
26597
26598
0
  default:
26599
0
      break;
26600
0
    }
26601
0
    return (ret);
26602
0
unexpected_elem:
26603
    /*
26604
    * Pop this element and set the skipDepth to skip
26605
    * all further content of the parent element.
26606
    */
26607
0
    vctxt->skipDepth = vctxt->depth;
26608
0
    vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED;
26609
0
    pielem->flags |= XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT;
26610
0
    return (ret);
26611
0
}
26612
26613
0
#define XML_SCHEMA_PUSH_TEXT_PERSIST 1
26614
0
#define XML_SCHEMA_PUSH_TEXT_CREATED 2
26615
0
#define XML_SCHEMA_PUSH_TEXT_VOLATILE 3
26616
26617
static int
26618
xmlSchemaVPushText(xmlSchemaValidCtxtPtr vctxt,
26619
      int nodeType, const xmlChar *value, int len,
26620
      int mode, int *consumed)
26621
0
{
26622
    /*
26623
    * Unfortunately we have to duplicate the text sometimes.
26624
    * OPTIMIZE: Maybe we could skip it, if:
26625
    *   1. content type is simple
26626
    *   2. whitespace is "collapse"
26627
    *   3. it consists of whitespace only
26628
    *
26629
    * Process character content.
26630
    */
26631
0
    if (consumed != NULL)
26632
0
  *consumed = 0;
26633
0
    if (INODE_NILLED(vctxt->inode)) {
26634
  /*
26635
  * SPEC cvc-elt (3.3.4 - 3.2.1)
26636
  * "The element information item must have no character or
26637
  * element information item [children]."
26638
  */
26639
0
  VERROR(XML_SCHEMAV_CVC_ELT_3_2_1, NULL,
26640
0
      "Neither character nor element content is allowed "
26641
0
      "because the element is 'nilled'");
26642
0
  return (vctxt->err);
26643
0
    }
26644
    /*
26645
    * SPEC (2.1) "If the {content type} is empty, then the
26646
    * element information item has no character or element
26647
    * information item [children]."
26648
    */
26649
0
    if (vctxt->inode->typeDef->contentType ==
26650
0
      XML_SCHEMA_CONTENT_EMPTY) {
26651
0
  VERROR(XML_SCHEMAV_CVC_COMPLEX_TYPE_2_1, NULL,
26652
0
      "Character content is not allowed, "
26653
0
      "because the content type is empty");
26654
0
  return (vctxt->err);
26655
0
    }
26656
26657
0
    if (vctxt->inode->typeDef->contentType ==
26658
0
      XML_SCHEMA_CONTENT_ELEMENTS) {
26659
0
  if ((nodeType != XML_TEXT_NODE) ||
26660
0
      (! xmlSchemaIsBlank((xmlChar *) value, len))) {
26661
      /*
26662
      * SPEC cvc-complex-type (2.3)
26663
      * "If the {content type} is element-only, then the
26664
      * element information item has no character information
26665
      * item [children] other than those whose [character
26666
      * code] is defined as a white space in [XML 1.0 (Second
26667
      * Edition)]."
26668
      */
26669
0
      VERROR(XML_SCHEMAV_CVC_COMPLEX_TYPE_2_3, NULL,
26670
0
    "Character content other than whitespace is not allowed "
26671
0
    "because the content type is 'element-only'");
26672
0
      return (vctxt->err);
26673
0
  }
26674
0
  return (0);
26675
0
    }
26676
26677
0
    if ((value == NULL) || (value[0] == 0))
26678
0
  return (0);
26679
    /*
26680
    * Save the value.
26681
    * NOTE that even if the content type is *mixed*, we need the
26682
    * *initial value* for default/fixed value constraints.
26683
    */
26684
0
    if ((vctxt->inode->typeDef->contentType == XML_SCHEMA_CONTENT_MIXED) &&
26685
0
  ((vctxt->inode->decl == NULL) ||
26686
0
  (vctxt->inode->decl->value == NULL)))
26687
0
  return (0);
26688
26689
0
    if (vctxt->inode->value == NULL) {
26690
  /*
26691
  * Set the value.
26692
  */
26693
0
  switch (mode) {
26694
0
      case XML_SCHEMA_PUSH_TEXT_PERSIST:
26695
    /*
26696
    * When working on a tree.
26697
    */
26698
0
    vctxt->inode->value = value;
26699
0
    vctxt->inode->flags &=
26700
0
        ~XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
26701
0
    break;
26702
0
      case XML_SCHEMA_PUSH_TEXT_CREATED:
26703
    /*
26704
    * When working with the reader.
26705
    * The value will be freed by the element info.
26706
    */
26707
0
    vctxt->inode->value = value;
26708
0
    if (consumed != NULL)
26709
0
        *consumed = 1;
26710
0
    vctxt->inode->flags |=
26711
0
        XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
26712
0
    break;
26713
0
      case XML_SCHEMA_PUSH_TEXT_VOLATILE:
26714
    /*
26715
    * When working with SAX.
26716
    * The value will be freed by the element info.
26717
    */
26718
0
    if (len != -1)
26719
0
        vctxt->inode->value = BAD_CAST xmlStrndup(value, len);
26720
0
    else
26721
0
        vctxt->inode->value = BAD_CAST xmlStrdup(value);
26722
0
    vctxt->inode->flags |=
26723
0
        XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
26724
0
    break;
26725
0
      default:
26726
0
    break;
26727
0
  }
26728
0
    } else {
26729
0
  if (len < 0)
26730
0
      len = xmlStrlen(value);
26731
  /*
26732
  * Concat the value.
26733
  */
26734
0
  if (vctxt->inode->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) {
26735
0
      vctxt->inode->value = BAD_CAST xmlStrncat(
26736
0
    (xmlChar *) vctxt->inode->value, value, len);
26737
0
  } else {
26738
0
      vctxt->inode->value =
26739
0
    BAD_CAST xmlStrncatNew(vctxt->inode->value, value, len);
26740
0
      vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
26741
0
  }
26742
0
    }
26743
26744
0
    return (0);
26745
0
}
26746
26747
static int
26748
xmlSchemaValidateElem(xmlSchemaValidCtxtPtr vctxt)
26749
0
{
26750
0
    int ret = 0;
26751
26752
0
    if ((vctxt->skipDepth != -1) &&
26753
0
  (vctxt->depth >= vctxt->skipDepth)) {
26754
0
  VERROR_INT("xmlSchemaValidateElem",
26755
0
      "in skip-state");
26756
0
  goto internal_error;
26757
0
    }
26758
0
    if (vctxt->xsiAssemble) {
26759
  /*
26760
  * We will stop validation if there was an error during
26761
  * dynamic schema construction.
26762
  * Note that we simply set @skipDepth to 0, this could
26763
  * mean that a streaming document via SAX would be
26764
  * still read to the end but it won't be validated any more.
26765
  * TODO: If we are sure how to stop the validation at once
26766
  *   for all input scenarios, then this should be changed to
26767
  *   instantly stop the validation.
26768
  */
26769
0
  ret = xmlSchemaAssembleByXSI(vctxt);
26770
0
  if (ret != 0) {
26771
0
      if (ret == -1)
26772
0
    goto internal_error;
26773
0
      vctxt->skipDepth = 0;
26774
0
      return(ret);
26775
0
  }
26776
        /*
26777
         * Augment the IDC definitions for the main schema and all imported ones
26778
         * NOTE: main schema is the first in the imported list
26779
         */
26780
0
        xmlHashScan(vctxt->schema->schemasImports, xmlSchemaAugmentImportedIDC,
26781
0
                    vctxt);
26782
0
    }
26783
0
    if (vctxt->depth > 0) {
26784
  /*
26785
  * Validate this element against the content model
26786
  * of the parent.
26787
  */
26788
0
  ret = xmlSchemaValidateChildElem(vctxt);
26789
0
  if (ret != 0) {
26790
0
      if (ret < 0) {
26791
0
    VERROR_INT("xmlSchemaValidateElem",
26792
0
        "calling xmlSchemaStreamValidateChildElement()");
26793
0
    goto internal_error;
26794
0
      }
26795
0
      goto exit;
26796
0
  }
26797
0
  if (vctxt->depth == vctxt->skipDepth)
26798
0
      goto exit;
26799
0
  if ((vctxt->inode->decl == NULL) &&
26800
0
      (vctxt->inode->typeDef == NULL)) {
26801
0
      VERROR_INT("xmlSchemaValidateElem",
26802
0
    "the child element was valid but neither the "
26803
0
    "declaration nor the type was set");
26804
0
      goto internal_error;
26805
0
  }
26806
0
    } else {
26807
  /*
26808
  * Get the declaration of the validation root.
26809
  */
26810
0
  vctxt->inode->decl = xmlSchemaGetElem(vctxt->schema,
26811
0
      vctxt->inode->localName,
26812
0
      vctxt->inode->nsName);
26813
0
  if (vctxt->inode->decl == NULL) {
26814
0
      ret = XML_SCHEMAV_CVC_ELT_1;
26815
0
      VERROR(ret, NULL,
26816
0
    "No matching global declaration available "
26817
0
    "for the validation root");
26818
0
      goto exit;
26819
0
  }
26820
0
    }
26821
26822
0
    if (vctxt->inode->decl == NULL)
26823
0
  goto type_validation;
26824
26825
0
    if (vctxt->inode->decl->type == XML_SCHEMA_TYPE_ANY) {
26826
0
  int skip;
26827
  /*
26828
  * Wildcards.
26829
  */
26830
0
  ret = xmlSchemaValidateElemWildcard(vctxt, &skip);
26831
0
  if (ret != 0) {
26832
0
      if (ret < 0) {
26833
0
    VERROR_INT("xmlSchemaValidateElem",
26834
0
        "calling xmlSchemaValidateElemWildcard()");
26835
0
    goto internal_error;
26836
0
      }
26837
0
      goto exit;
26838
0
  }
26839
0
  if (skip) {
26840
0
      vctxt->skipDepth = vctxt->depth;
26841
0
      goto exit;
26842
0
  }
26843
  /*
26844
  * The declaration might be set by the wildcard validation,
26845
  * when the processContents is "lax" or "strict".
26846
  */
26847
0
  if (vctxt->inode->decl->type != XML_SCHEMA_TYPE_ELEMENT) {
26848
      /*
26849
      * Clear the "decl" field to not confuse further processing.
26850
      */
26851
0
      vctxt->inode->decl = NULL;
26852
0
      goto type_validation;
26853
0
  }
26854
0
    }
26855
    /*
26856
    * Validate against the declaration.
26857
    */
26858
0
    ret = xmlSchemaValidateElemDecl(vctxt);
26859
0
    if (ret != 0) {
26860
0
  if (ret < 0) {
26861
0
      VERROR_INT("xmlSchemaValidateElem",
26862
0
    "calling xmlSchemaValidateElemDecl()");
26863
0
      goto internal_error;
26864
0
  }
26865
0
  goto exit;
26866
0
    }
26867
    /*
26868
    * Validate against the type definition.
26869
    */
26870
0
type_validation:
26871
26872
0
    if (vctxt->inode->typeDef == NULL) {
26873
0
  vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE;
26874
0
  ret = XML_SCHEMAV_CVC_TYPE_1;
26875
0
  VERROR(ret, NULL,
26876
0
      "The type definition is absent");
26877
0
  goto exit;
26878
0
    }
26879
0
    if (vctxt->inode->typeDef->flags & XML_SCHEMAS_TYPE_ABSTRACT) {
26880
0
  vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE;
26881
0
  ret = XML_SCHEMAV_CVC_TYPE_2;
26882
0
      VERROR(ret, NULL,
26883
0
      "The type definition is abstract");
26884
0
  goto exit;
26885
0
    }
26886
    /*
26887
    * Evaluate IDCs. Do it here, since new IDC matchers are registered
26888
    * during validation against the declaration. This must be done
26889
    * _before_ attribute validation.
26890
    */
26891
0
    if (vctxt->xpathStates != NULL) {
26892
0
  ret = xmlSchemaXPathEvaluate(vctxt, XML_ELEMENT_NODE);
26893
0
  vctxt->inode->appliedXPath = 1;
26894
0
  if (ret == -1) {
26895
0
      VERROR_INT("xmlSchemaValidateElem",
26896
0
    "calling xmlSchemaXPathEvaluate()");
26897
0
      goto internal_error;
26898
0
  }
26899
0
    }
26900
    /*
26901
    * Validate attributes.
26902
    */
26903
0
    if (WXS_IS_COMPLEX(vctxt->inode->typeDef)) {
26904
0
  if ((vctxt->nbAttrInfos != 0) ||
26905
0
      (vctxt->inode->typeDef->attrUses != NULL)) {
26906
26907
0
      ret = xmlSchemaVAttributesComplex(vctxt);
26908
0
  }
26909
0
    } else if (vctxt->nbAttrInfos != 0) {
26910
26911
0
  ret = xmlSchemaVAttributesSimple(vctxt);
26912
0
    }
26913
    /*
26914
    * Clear registered attributes.
26915
    */
26916
0
    if (vctxt->nbAttrInfos != 0)
26917
0
  xmlSchemaClearAttrInfos(vctxt);
26918
0
    if (ret == -1) {
26919
0
  VERROR_INT("xmlSchemaValidateElem",
26920
0
      "calling attributes validation");
26921
0
  goto internal_error;
26922
0
    }
26923
    /*
26924
    * Don't return an error if attributes are invalid on purpose.
26925
    */
26926
0
    ret = 0;
26927
26928
0
exit:
26929
0
    if (ret != 0)
26930
0
  vctxt->skipDepth = vctxt->depth;
26931
0
    return (ret);
26932
0
internal_error:
26933
0
    return (-1);
26934
0
}
26935
26936
#ifdef XML_SCHEMA_READER_ENABLED
26937
static int
26938
xmlSchemaVReaderWalk(xmlSchemaValidCtxtPtr vctxt)
26939
{
26940
    const int WHTSP = 13, SIGN_WHTSP = 14, END_ELEM = 15;
26941
    int depth, nodeType, ret = 0, consumed;
26942
    xmlSchemaNodeInfoPtr ielem;
26943
26944
    vctxt->depth = -1;
26945
    ret = xmlTextReaderRead(vctxt->reader);
26946
    /*
26947
    * Move to the document element.
26948
    */
26949
    while (ret == 1) {
26950
  nodeType = xmlTextReaderNodeType(vctxt->reader);
26951
  if (nodeType == XML_ELEMENT_NODE)
26952
      goto root_found;
26953
  ret = xmlTextReaderRead(vctxt->reader);
26954
    }
26955
    goto exit;
26956
26957
root_found:
26958
26959
    do {
26960
  depth = xmlTextReaderDepth(vctxt->reader);
26961
  nodeType = xmlTextReaderNodeType(vctxt->reader);
26962
26963
  if (nodeType == XML_ELEMENT_NODE) {
26964
26965
      vctxt->depth++;
26966
      if (xmlSchemaValidatorPushElem(vctxt) == -1) {
26967
    VERROR_INT("xmlSchemaVReaderWalk",
26968
        "calling xmlSchemaValidatorPushElem()");
26969
    goto internal_error;
26970
      }
26971
      ielem = vctxt->inode;
26972
      ielem->localName = xmlTextReaderLocalName(vctxt->reader);
26973
      ielem->nsName = xmlTextReaderNamespaceUri(vctxt->reader);
26974
      ielem->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES;
26975
      /*
26976
      * Is the element empty?
26977
      */
26978
      ret = xmlTextReaderIsEmptyElement(vctxt->reader);
26979
      if (ret == -1) {
26980
    VERROR_INT("xmlSchemaVReaderWalk",
26981
        "calling xmlTextReaderIsEmptyElement()");
26982
    goto internal_error;
26983
      }
26984
      if (ret) {
26985
    ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY;
26986
      }
26987
      /*
26988
      * Register attributes.
26989
      */
26990
      vctxt->nbAttrInfos = 0;
26991
      ret = xmlTextReaderMoveToFirstAttribute(vctxt->reader);
26992
      if (ret == -1) {
26993
    VERROR_INT("xmlSchemaVReaderWalk",
26994
        "calling xmlTextReaderMoveToFirstAttribute()");
26995
    goto internal_error;
26996
      }
26997
      if (ret == 1) {
26998
    do {
26999
        /*
27000
        * VAL TODO: How do we know that the reader works on a
27001
        * node tree, to be able to pass a node here?
27002
        */
27003
        if (xmlSchemaValidatorPushAttribute(vctxt, NULL,
27004
      (const xmlChar *) xmlTextReaderLocalName(vctxt->reader),
27005
      xmlTextReaderNamespaceUri(vctxt->reader), 1,
27006
      xmlTextReaderValue(vctxt->reader), 1) == -1) {
27007
27008
      VERROR_INT("xmlSchemaVReaderWalk",
27009
          "calling xmlSchemaValidatorPushAttribute()");
27010
      goto internal_error;
27011
        }
27012
        ret = xmlTextReaderMoveToNextAttribute(vctxt->reader);
27013
        if (ret == -1) {
27014
      VERROR_INT("xmlSchemaVReaderWalk",
27015
          "calling xmlTextReaderMoveToFirstAttribute()");
27016
      goto internal_error;
27017
        }
27018
    } while (ret == 1);
27019
    /*
27020
    * Back to element position.
27021
    */
27022
    ret = xmlTextReaderMoveToElement(vctxt->reader);
27023
    if (ret == -1) {
27024
        VERROR_INT("xmlSchemaVReaderWalk",
27025
      "calling xmlTextReaderMoveToElement()");
27026
        goto internal_error;
27027
    }
27028
      }
27029
      /*
27030
      * Validate the element.
27031
      */
27032
      ret= xmlSchemaValidateElem(vctxt);
27033
      if (ret != 0) {
27034
    if (ret == -1) {
27035
        VERROR_INT("xmlSchemaVReaderWalk",
27036
      "calling xmlSchemaValidateElem()");
27037
        goto internal_error;
27038
    }
27039
    goto exit;
27040
      }
27041
      if (vctxt->depth == vctxt->skipDepth) {
27042
    int curDepth;
27043
    /*
27044
    * Skip all content.
27045
    */
27046
    if ((ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY) == 0) {
27047
        ret = xmlTextReaderRead(vctxt->reader);
27048
        curDepth = xmlTextReaderDepth(vctxt->reader);
27049
        while ((ret == 1) && (curDepth != depth)) {
27050
      ret = xmlTextReaderRead(vctxt->reader);
27051
      curDepth = xmlTextReaderDepth(vctxt->reader);
27052
        }
27053
        if (ret < 0) {
27054
      /*
27055
      * VAL TODO: A reader error occurred; what to do here?
27056
      */
27057
      ret = 1;
27058
      goto exit;
27059
        }
27060
    }
27061
    goto leave_elem;
27062
      }
27063
      /*
27064
      * READER VAL TODO: Is an END_ELEM really never called
27065
      * if the elem is empty?
27066
      */
27067
      if (ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
27068
    goto leave_elem;
27069
  } else if (nodeType == END_ELEM) {
27070
      /*
27071
      * Process END of element.
27072
      */
27073
leave_elem:
27074
      ret = xmlSchemaValidatorPopElem(vctxt);
27075
      if (ret != 0) {
27076
    if (ret < 0) {
27077
        VERROR_INT("xmlSchemaVReaderWalk",
27078
      "calling xmlSchemaValidatorPopElem()");
27079
        goto internal_error;
27080
    }
27081
    goto exit;
27082
      }
27083
      if (vctxt->depth >= 0)
27084
    ielem = vctxt->inode;
27085
      else
27086
    ielem = NULL;
27087
  } else if ((nodeType == XML_TEXT_NODE) ||
27088
      (nodeType == XML_CDATA_SECTION_NODE) ||
27089
      (nodeType == WHTSP) ||
27090
      (nodeType == SIGN_WHTSP)) {
27091
      /*
27092
      * Process character content.
27093
      */
27094
      xmlChar *value;
27095
27096
      if ((nodeType == WHTSP) || (nodeType == SIGN_WHTSP))
27097
    nodeType = XML_TEXT_NODE;
27098
27099
      value = xmlTextReaderValue(vctxt->reader);
27100
      ret = xmlSchemaVPushText(vctxt, nodeType, BAD_CAST value,
27101
    -1, XML_SCHEMA_PUSH_TEXT_CREATED, &consumed);
27102
      if (! consumed)
27103
    xmlFree(value);
27104
      if (ret == -1) {
27105
    VERROR_INT("xmlSchemaVReaderWalk",
27106
        "calling xmlSchemaVPushText()");
27107
    goto internal_error;
27108
      }
27109
  } else if ((nodeType == XML_ENTITY_NODE) ||
27110
      (nodeType == XML_ENTITY_REF_NODE)) {
27111
      /*
27112
      * VAL TODO: What to do with entities?
27113
      */
27114
      TODO
27115
  }
27116
  /*
27117
  * Read next node.
27118
  */
27119
  ret = xmlTextReaderRead(vctxt->reader);
27120
    } while (ret == 1);
27121
27122
exit:
27123
    return (ret);
27124
internal_error:
27125
    return (-1);
27126
}
27127
#endif
27128
27129
/************************************************************************
27130
 *                  *
27131
 *      SAX validation handlers       *
27132
 *                  *
27133
 ************************************************************************/
27134
27135
/*
27136
* Process text content.
27137
*/
27138
static void
27139
xmlSchemaSAXHandleText(void *ctx,
27140
           const xmlChar * ch,
27141
           int len)
27142
0
{
27143
0
    xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
27144
27145
0
    if (vctxt->depth < 0)
27146
0
  return;
27147
0
    if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
27148
0
  return;
27149
0
    if (vctxt->inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
27150
0
  vctxt->inode->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
27151
0
    if (xmlSchemaVPushText(vctxt, XML_TEXT_NODE, ch, len,
27152
0
  XML_SCHEMA_PUSH_TEXT_VOLATILE, NULL) == -1) {
27153
0
  VERROR_INT("xmlSchemaSAXHandleCDataSection",
27154
0
      "calling xmlSchemaVPushText()");
27155
0
  vctxt->err = -1;
27156
0
  xmlStopParser(vctxt->parserCtxt);
27157
0
    }
27158
0
}
27159
27160
/*
27161
* Process CDATA content.
27162
*/
27163
static void
27164
xmlSchemaSAXHandleCDataSection(void *ctx,
27165
           const xmlChar * ch,
27166
           int len)
27167
0
{
27168
0
    xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
27169
27170
0
    if (vctxt->depth < 0)
27171
0
  return;
27172
0
    if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
27173
0
  return;
27174
0
    if (vctxt->inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
27175
0
  vctxt->inode->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
27176
0
    if (xmlSchemaVPushText(vctxt, XML_CDATA_SECTION_NODE, ch, len,
27177
0
  XML_SCHEMA_PUSH_TEXT_VOLATILE, NULL) == -1) {
27178
0
  VERROR_INT("xmlSchemaSAXHandleCDataSection",
27179
0
      "calling xmlSchemaVPushText()");
27180
0
  vctxt->err = -1;
27181
0
  xmlStopParser(vctxt->parserCtxt);
27182
0
    }
27183
0
}
27184
27185
static void
27186
xmlSchemaSAXHandleReference(void *ctx ATTRIBUTE_UNUSED,
27187
          const xmlChar * name ATTRIBUTE_UNUSED)
27188
0
{
27189
0
    xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
27190
27191
0
    if (vctxt->depth < 0)
27192
0
  return;
27193
0
    if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
27194
0
  return;
27195
    /* SAX VAL TODO: What to do here? */
27196
0
}
27197
27198
static void
27199
xmlSchemaSAXHandleStartElementNs(void *ctx,
27200
         const xmlChar * localname,
27201
         const xmlChar * prefix ATTRIBUTE_UNUSED,
27202
         const xmlChar * URI,
27203
         int nb_namespaces,
27204
         const xmlChar ** namespaces,
27205
         int nb_attributes,
27206
         int nb_defaulted ATTRIBUTE_UNUSED,
27207
         const xmlChar ** attributes)
27208
0
{
27209
0
    xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
27210
0
    int ret;
27211
0
    xmlSchemaNodeInfoPtr ielem;
27212
0
    int i, j;
27213
27214
    /*
27215
    * SAX VAL TODO: What to do with nb_defaulted?
27216
    */
27217
    /*
27218
    * Skip elements if inside a "skip" wildcard or invalid.
27219
    */
27220
0
    vctxt->depth++;
27221
0
    if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
27222
0
  return;
27223
    /*
27224
    * Push the element.
27225
    */
27226
0
    if (xmlSchemaValidatorPushElem(vctxt) == -1) {
27227
0
  VERROR_INT("xmlSchemaSAXHandleStartElementNs",
27228
0
      "calling xmlSchemaValidatorPushElem()");
27229
0
  goto internal_error;
27230
0
    }
27231
0
    ielem = vctxt->inode;
27232
    /*
27233
    * TODO: Is this OK?
27234
    */
27235
0
    ielem->nodeLine = xmlSAX2GetLineNumber(vctxt->parserCtxt);
27236
0
    ielem->localName = localname;
27237
0
    ielem->nsName = URI;
27238
0
    ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY;
27239
    /*
27240
    * Register namespaces on the elem info.
27241
    */
27242
0
    if (nb_namespaces != 0) {
27243
  /*
27244
  * Although the parser builds its own namespace list,
27245
  * we have no access to it, so we'll use an own one.
27246
  */
27247
0
        for (i = 0, j = 0; i < nb_namespaces; i++, j += 2) {
27248
      /*
27249
      * Store prefix and namespace name.
27250
      */
27251
0
            if (ielem->sizeNsBindings <= ielem->nbNsBindings) {
27252
0
                const xmlChar **tmp;
27253
0
                size_t elemSize = 2 * sizeof(tmp[0]);
27254
0
                int newSize;
27255
27256
0
                newSize = xmlGrowCapacity(ielem->sizeNsBindings, elemSize,
27257
0
                                          5, XML_MAX_ITEMS);
27258
0
                if (newSize < 0) {
27259
0
                    xmlSchemaVErrMemory(vctxt);
27260
0
                    goto internal_error;
27261
0
                }
27262
0
                tmp = xmlRealloc(ielem->nsBindings, newSize * elemSize);
27263
0
                if (tmp == NULL) {
27264
0
                    xmlSchemaVErrMemory(vctxt);
27265
0
                    goto internal_error;
27266
0
                }
27267
27268
0
                ielem->nsBindings = tmp;
27269
0
                ielem->sizeNsBindings = newSize;
27270
0
      }
27271
27272
0
      ielem->nsBindings[ielem->nbNsBindings * 2] = namespaces[j];
27273
0
      if (namespaces[j+1][0] == 0) {
27274
    /*
27275
    * Handle xmlns="".
27276
    */
27277
0
    ielem->nsBindings[ielem->nbNsBindings * 2 + 1] = NULL;
27278
0
      } else
27279
0
    ielem->nsBindings[ielem->nbNsBindings * 2 + 1] =
27280
0
        namespaces[j+1];
27281
0
      ielem->nbNsBindings++;
27282
0
  }
27283
0
    }
27284
    /*
27285
    * Register attributes.
27286
    * SAX VAL TODO: We are not adding namespace declaration
27287
    * attributes yet.
27288
    */
27289
0
    if (nb_attributes != 0) {
27290
0
  int valueLen, k, l;
27291
0
  xmlChar *value;
27292
27293
0
        for (j = 0, i = 0; i < nb_attributes; i++, j += 5) {
27294
      /*
27295
      * Duplicate the value, changing any &#38; to a literal ampersand.
27296
      *
27297
      * libxml2 differs from normal SAX here in that it escapes all ampersands
27298
      * as &#38; instead of delivering the raw converted string. Changing the
27299
      * behavior at this point would break applications that use this API, so
27300
      * we are forced to work around it.
27301
      */
27302
0
      valueLen = attributes[j+4] - attributes[j+3];
27303
0
      value = xmlMalloc(valueLen + 1);
27304
0
      if (value == NULL) {
27305
0
    xmlSchemaVErrMemory(vctxt);
27306
0
    goto internal_error;
27307
0
      }
27308
0
      for (k = 0, l = 0; k < valueLen; l++) {
27309
0
    if (k < valueLen - 4 &&
27310
0
        attributes[j+3][k+0] == '&' &&
27311
0
        attributes[j+3][k+1] == '#' &&
27312
0
        attributes[j+3][k+2] == '3' &&
27313
0
        attributes[j+3][k+3] == '8' &&
27314
0
        attributes[j+3][k+4] == ';') {
27315
0
        value[l] = '&';
27316
0
        k += 5;
27317
0
    } else {
27318
0
        value[l] = attributes[j+3][k];
27319
0
        k++;
27320
0
    }
27321
0
      }
27322
0
      value[l] = '\0';
27323
      /*
27324
      * TODO: Set the node line.
27325
      */
27326
0
      ret = xmlSchemaValidatorPushAttribute(vctxt,
27327
0
    NULL, ielem->nodeLine, attributes[j], attributes[j+2], 0,
27328
0
    value, 1);
27329
0
      if (ret == -1) {
27330
0
    VERROR_INT("xmlSchemaSAXHandleStartElementNs",
27331
0
        "calling xmlSchemaValidatorPushAttribute()");
27332
0
    goto internal_error;
27333
0
      }
27334
0
  }
27335
0
    }
27336
    /*
27337
    * Validate the element.
27338
    */
27339
0
    ret = xmlSchemaValidateElem(vctxt);
27340
0
    if (ret != 0) {
27341
0
  if (ret == -1) {
27342
0
      VERROR_INT("xmlSchemaSAXHandleStartElementNs",
27343
0
    "calling xmlSchemaValidateElem()");
27344
0
      goto internal_error;
27345
0
  }
27346
0
  goto exit;
27347
0
    }
27348
27349
0
exit:
27350
0
    return;
27351
0
internal_error:
27352
0
    vctxt->err = -1;
27353
0
    xmlStopParser(vctxt->parserCtxt);
27354
0
}
27355
27356
static void
27357
xmlSchemaSAXHandleEndElementNs(void *ctx,
27358
             const xmlChar * localname ATTRIBUTE_UNUSED,
27359
             const xmlChar * prefix ATTRIBUTE_UNUSED,
27360
             const xmlChar * URI ATTRIBUTE_UNUSED)
27361
0
{
27362
0
    xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
27363
0
    int res;
27364
27365
    /*
27366
    * Skip elements if inside a "skip" wildcard or if invalid.
27367
    */
27368
0
    if (vctxt->skipDepth != -1) {
27369
0
  if (vctxt->depth > vctxt->skipDepth) {
27370
0
      vctxt->depth--;
27371
0
      return;
27372
0
  } else
27373
0
      vctxt->skipDepth = -1;
27374
0
    }
27375
    /*
27376
    * SAX VAL TODO: Just a temporary check.
27377
    */
27378
0
    if ((!xmlStrEqual(vctxt->inode->localName, localname)) ||
27379
0
  (!xmlStrEqual(vctxt->inode->nsName, URI))) {
27380
0
  VERROR_INT("xmlSchemaSAXHandleEndElementNs",
27381
0
      "elem pop mismatch");
27382
0
    }
27383
0
    res = xmlSchemaValidatorPopElem(vctxt);
27384
0
    if (res != 0) {
27385
0
  if (res < 0) {
27386
0
      VERROR_INT("xmlSchemaSAXHandleEndElementNs",
27387
0
    "calling xmlSchemaValidatorPopElem()");
27388
0
      goto internal_error;
27389
0
  }
27390
0
  goto exit;
27391
0
    }
27392
0
exit:
27393
0
    return;
27394
0
internal_error:
27395
0
    vctxt->err = -1;
27396
0
    xmlStopParser(vctxt->parserCtxt);
27397
0
}
27398
27399
/************************************************************************
27400
 *                  *
27401
 *      Validation interfaces       *
27402
 *                  *
27403
 ************************************************************************/
27404
27405
/**
27406
 * xmlSchemaNewValidCtxt:
27407
 * @schema:  a precompiled XML Schemas
27408
 *
27409
 * Create an XML Schemas validation context based on the given schema.
27410
 *
27411
 * Returns the validation context or NULL in case of error
27412
 */
27413
xmlSchemaValidCtxtPtr
27414
xmlSchemaNewValidCtxt(xmlSchemaPtr schema)
27415
0
{
27416
0
    xmlSchemaValidCtxtPtr ret;
27417
27418
0
    ret = (xmlSchemaValidCtxtPtr) xmlMalloc(sizeof(xmlSchemaValidCtxt));
27419
0
    if (ret == NULL) {
27420
0
        xmlSchemaVErrMemory(NULL);
27421
0
        return (NULL);
27422
0
    }
27423
0
    memset(ret, 0, sizeof(xmlSchemaValidCtxt));
27424
0
    ret->type = XML_SCHEMA_CTXT_VALIDATOR;
27425
0
    ret->dict = xmlDictCreate();
27426
0
    if (ret->dict == NULL) {
27427
0
        xmlSchemaFreeValidCtxt(ret);
27428
0
        return(NULL);
27429
0
    }
27430
0
    ret->nodeQNames = xmlSchemaItemListCreate();
27431
0
    if (ret->nodeQNames == NULL) {
27432
0
        xmlSchemaFreeValidCtxt(ret);
27433
0
        return(NULL);
27434
0
    }
27435
0
    ret->schema = schema;
27436
0
    return (ret);
27437
0
}
27438
27439
/**
27440
 * xmlSchemaValidateSetFilename:
27441
 * @vctxt: the schema validation context
27442
 * @filename: the file name
27443
 *
27444
 * Workaround to provide file error reporting information when this is
27445
 * not provided by current APIs
27446
 */
27447
void
27448
0
xmlSchemaValidateSetFilename(xmlSchemaValidCtxtPtr vctxt, const char *filename) {
27449
0
    if (vctxt == NULL)
27450
0
        return;
27451
0
    if (vctxt->filename != NULL)
27452
0
        xmlFree(vctxt->filename);
27453
0
    if (filename != NULL)
27454
0
        vctxt->filename = (char *) xmlStrdup((const xmlChar *) filename);
27455
0
    else
27456
0
        vctxt->filename = NULL;
27457
0
}
27458
27459
/**
27460
 * xmlSchemaClearValidCtxt:
27461
 * @vctxt: the schema validation context
27462
 *
27463
 * Free the resources associated to the schema validation context;
27464
 * leaves some fields alive intended for reuse of the context.
27465
 */
27466
static void
27467
xmlSchemaClearValidCtxt(xmlSchemaValidCtxtPtr vctxt)
27468
0
{
27469
0
    if (vctxt == NULL)
27470
0
        return;
27471
27472
    /*
27473
    * TODO: Should we clear the flags?
27474
    *   Might be problematic if one reuses the context
27475
    *   and assumes that the options remain the same.
27476
    */
27477
0
    vctxt->flags = 0;
27478
0
    vctxt->validationRoot = NULL;
27479
0
    vctxt->doc = NULL;
27480
0
#ifdef LIBXML_READER_ENABLED
27481
0
    vctxt->reader = NULL;
27482
0
#endif
27483
0
    vctxt->hasKeyrefs = 0;
27484
27485
0
    if (vctxt->value != NULL) {
27486
0
        xmlSchemaFreeValue(vctxt->value);
27487
0
  vctxt->value = NULL;
27488
0
    }
27489
    /*
27490
    * Augmented IDC information.
27491
    */
27492
0
    if (vctxt->aidcs != NULL) {
27493
0
  xmlSchemaIDCAugPtr cur = vctxt->aidcs, next;
27494
0
  do {
27495
0
      next = cur->next;
27496
0
      xmlFree(cur);
27497
0
      cur = next;
27498
0
  } while (cur != NULL);
27499
0
  vctxt->aidcs = NULL;
27500
0
    }
27501
27502
0
    if (vctxt->idcNodes != NULL) {
27503
0
  int i;
27504
0
  xmlSchemaPSVIIDCNodePtr item;
27505
27506
0
  for (i = 0; i < vctxt->nbIdcNodes; i++) {
27507
0
      item = vctxt->idcNodes[i];
27508
0
      xmlFree(item->keys);
27509
0
      xmlFree(item);
27510
0
  }
27511
0
  xmlFree(vctxt->idcNodes);
27512
0
  vctxt->idcNodes = NULL;
27513
0
  vctxt->nbIdcNodes = 0;
27514
0
  vctxt->sizeIdcNodes = 0;
27515
0
    }
27516
27517
0
    if (vctxt->idcKeys != NULL) {
27518
0
  int i;
27519
0
  for (i = 0; i < vctxt->nbIdcKeys; i++)
27520
0
      xmlSchemaIDCFreeKey(vctxt->idcKeys[i]);
27521
0
  xmlFree(vctxt->idcKeys);
27522
0
  vctxt->idcKeys = NULL;
27523
0
  vctxt->nbIdcKeys = 0;
27524
0
  vctxt->sizeIdcKeys = 0;
27525
0
    }
27526
27527
    /*
27528
    * Note that we won't delete the XPath state pool here.
27529
    */
27530
0
    if (vctxt->xpathStates != NULL) {
27531
0
  xmlSchemaFreeIDCStateObjList(vctxt->xpathStates);
27532
0
  vctxt->xpathStates = NULL;
27533
0
    }
27534
    /*
27535
    * Attribute info.
27536
    */
27537
0
    if (vctxt->nbAttrInfos != 0) {
27538
0
  xmlSchemaClearAttrInfos(vctxt);
27539
0
    }
27540
    /*
27541
    * Element info.
27542
    */
27543
0
    if (vctxt->elemInfos != NULL) {
27544
0
  int i;
27545
0
  xmlSchemaNodeInfoPtr ei;
27546
27547
0
  for (i = 0; i < vctxt->sizeElemInfos; i++) {
27548
0
      ei = vctxt->elemInfos[i];
27549
0
      if (ei == NULL)
27550
0
    break;
27551
0
      xmlSchemaClearElemInfo(vctxt, ei);
27552
0
  }
27553
0
    }
27554
0
    xmlSchemaItemListClear(vctxt->nodeQNames);
27555
    /* Recreate the dict. */
27556
0
    xmlDictFree(vctxt->dict);
27557
    /*
27558
    * TODO: Is is save to recreate it? Do we have a scenario
27559
    * where the user provides the dict?
27560
    */
27561
0
    vctxt->dict = xmlDictCreate();
27562
27563
0
    if (vctxt->filename != NULL) {
27564
0
        xmlFree(vctxt->filename);
27565
0
  vctxt->filename = NULL;
27566
0
    }
27567
27568
    /*
27569
     * Note that some cleanup functions can move items to the cache,
27570
     * so the cache shouldn't be freed too early.
27571
     */
27572
0
    if (vctxt->idcMatcherCache != NULL) {
27573
0
  xmlSchemaIDCMatcherPtr matcher = vctxt->idcMatcherCache, tmp;
27574
27575
0
  while (matcher) {
27576
0
      tmp = matcher;
27577
0
      matcher = matcher->nextCached;
27578
0
      xmlSchemaIDCFreeMatcherList(tmp);
27579
0
  }
27580
0
  vctxt->idcMatcherCache = NULL;
27581
0
    }
27582
0
}
27583
27584
/**
27585
 * xmlSchemaFreeValidCtxt:
27586
 * @ctxt:  the schema validation context
27587
 *
27588
 * Free the resources associated to the schema validation context
27589
 */
27590
void
27591
xmlSchemaFreeValidCtxt(xmlSchemaValidCtxtPtr ctxt)
27592
0
{
27593
0
    if (ctxt == NULL)
27594
0
        return;
27595
0
    if (ctxt->value != NULL)
27596
0
        xmlSchemaFreeValue(ctxt->value);
27597
0
    if (ctxt->pctxt != NULL)
27598
0
  xmlSchemaFreeParserCtxt(ctxt->pctxt);
27599
0
    if (ctxt->idcNodes != NULL) {
27600
0
  int i;
27601
0
  xmlSchemaPSVIIDCNodePtr item;
27602
27603
0
  for (i = 0; i < ctxt->nbIdcNodes; i++) {
27604
0
      item = ctxt->idcNodes[i];
27605
0
      xmlFree(item->keys);
27606
0
      xmlFree(item);
27607
0
  }
27608
0
  xmlFree(ctxt->idcNodes);
27609
0
    }
27610
0
    if (ctxt->idcKeys != NULL) {
27611
0
  int i;
27612
0
  for (i = 0; i < ctxt->nbIdcKeys; i++)
27613
0
      xmlSchemaIDCFreeKey(ctxt->idcKeys[i]);
27614
0
  xmlFree(ctxt->idcKeys);
27615
0
    }
27616
27617
0
    if (ctxt->xpathStates != NULL) {
27618
0
  xmlSchemaFreeIDCStateObjList(ctxt->xpathStates);
27619
0
  ctxt->xpathStates = NULL;
27620
0
    }
27621
0
    if (ctxt->xpathStatePool != NULL) {
27622
0
  xmlSchemaFreeIDCStateObjList(ctxt->xpathStatePool);
27623
0
  ctxt->xpathStatePool = NULL;
27624
0
    }
27625
27626
    /*
27627
    * Augmented IDC information.
27628
    */
27629
0
    if (ctxt->aidcs != NULL) {
27630
0
  xmlSchemaIDCAugPtr cur = ctxt->aidcs, next;
27631
0
  do {
27632
0
      next = cur->next;
27633
0
      xmlFree(cur);
27634
0
      cur = next;
27635
0
  } while (cur != NULL);
27636
0
    }
27637
0
    if (ctxt->attrInfos != NULL) {
27638
0
  int i;
27639
0
  xmlSchemaAttrInfoPtr attr;
27640
27641
  /* Just a paranoid call to the cleanup. */
27642
0
  if (ctxt->nbAttrInfos != 0)
27643
0
      xmlSchemaClearAttrInfos(ctxt);
27644
0
  for (i = 0; i < ctxt->sizeAttrInfos; i++) {
27645
0
      attr = ctxt->attrInfos[i];
27646
0
      xmlFree(attr);
27647
0
  }
27648
0
  xmlFree(ctxt->attrInfos);
27649
0
    }
27650
0
    if (ctxt->elemInfos != NULL) {
27651
0
  int i;
27652
0
  xmlSchemaNodeInfoPtr ei;
27653
27654
0
  for (i = 0; i < ctxt->sizeElemInfos; i++) {
27655
0
      ei = ctxt->elemInfos[i];
27656
0
      if (ei == NULL)
27657
0
    break;
27658
0
      xmlSchemaClearElemInfo(ctxt, ei);
27659
0
      xmlFree(ei);
27660
0
  }
27661
0
  xmlFree(ctxt->elemInfos);
27662
0
    }
27663
0
    if (ctxt->nodeQNames != NULL)
27664
0
  xmlSchemaItemListFree(ctxt->nodeQNames);
27665
0
    if (ctxt->dict != NULL)
27666
0
  xmlDictFree(ctxt->dict);
27667
0
    if (ctxt->filename != NULL)
27668
0
  xmlFree(ctxt->filename);
27669
0
    xmlFree(ctxt);
27670
0
}
27671
27672
/**
27673
 * xmlSchemaIsValid:
27674
 * @ctxt: the schema validation context
27675
 *
27676
 * Check if any error was detected during validation.
27677
 *
27678
 * Returns 1 if valid so far, 0 if errors were detected, and -1 in case
27679
 *         of internal error.
27680
 */
27681
int
27682
xmlSchemaIsValid(xmlSchemaValidCtxtPtr ctxt)
27683
0
{
27684
0
    if (ctxt == NULL)
27685
0
        return(-1);
27686
0
    return(ctxt->err == 0);
27687
0
}
27688
27689
/**
27690
 * xmlSchemaSetValidErrors:
27691
 * @ctxt:  a schema validation context
27692
 * @err:  the error function
27693
 * @warn: the warning function
27694
 * @ctx: the functions context
27695
 *
27696
 * DEPRECATED: Use xmlSchemaSetValidStructuredErrors.
27697
 *
27698
 * Set the error and warning callback information
27699
 */
27700
void
27701
xmlSchemaSetValidErrors(xmlSchemaValidCtxtPtr ctxt,
27702
                        xmlSchemaValidityErrorFunc err,
27703
                        xmlSchemaValidityWarningFunc warn, void *ctx)
27704
0
{
27705
0
    if (ctxt == NULL)
27706
0
        return;
27707
0
    ctxt->error = err;
27708
0
    ctxt->warning = warn;
27709
0
    ctxt->errCtxt = ctx;
27710
0
    if (ctxt->pctxt != NULL)
27711
0
  xmlSchemaSetParserErrors(ctxt->pctxt, err, warn, ctx);
27712
0
}
27713
27714
/**
27715
 * xmlSchemaSetValidStructuredErrors:
27716
 * @ctxt:  a schema validation context
27717
 * @serror:  the structured error function
27718
 * @ctx: the functions context
27719
 *
27720
 * Set the structured error callback
27721
 */
27722
void
27723
xmlSchemaSetValidStructuredErrors(xmlSchemaValidCtxtPtr ctxt,
27724
          xmlStructuredErrorFunc serror, void *ctx)
27725
0
{
27726
0
    if (ctxt == NULL)
27727
0
        return;
27728
0
    ctxt->serror = serror;
27729
0
    ctxt->error = NULL;
27730
0
    ctxt->warning = NULL;
27731
0
    ctxt->errCtxt = ctx;
27732
0
    if (ctxt->pctxt != NULL)
27733
0
  xmlSchemaSetParserStructuredErrors(ctxt->pctxt, serror, ctx);
27734
0
}
27735
27736
/**
27737
 * xmlSchemaGetValidErrors:
27738
 * @ctxt: a XML-Schema validation context
27739
 * @err: the error function result
27740
 * @warn: the warning function result
27741
 * @ctx: the functions context result
27742
 *
27743
 * Get the error and warning callback information
27744
 *
27745
 * Returns -1 in case of error and 0 otherwise
27746
 */
27747
int
27748
xmlSchemaGetValidErrors(xmlSchemaValidCtxtPtr ctxt,
27749
      xmlSchemaValidityErrorFunc * err,
27750
      xmlSchemaValidityWarningFunc * warn, void **ctx)
27751
0
{
27752
0
  if (ctxt == NULL)
27753
0
    return (-1);
27754
0
  if (err != NULL)
27755
0
    *err = ctxt->error;
27756
0
  if (warn != NULL)
27757
0
    *warn = ctxt->warning;
27758
0
  if (ctx != NULL)
27759
0
    *ctx = ctxt->errCtxt;
27760
0
  return (0);
27761
0
}
27762
27763
27764
/**
27765
 * xmlSchemaSetValidOptions:
27766
 * @ctxt: a schema validation context
27767
 * @options: a combination of xmlSchemaValidOption
27768
 *
27769
 * Sets the options to be used during the validation.
27770
 *
27771
 * Returns 0 in case of success, -1 in case of an
27772
 * API error.
27773
 */
27774
int
27775
xmlSchemaSetValidOptions(xmlSchemaValidCtxtPtr ctxt,
27776
       int options)
27777
27778
0
{
27779
0
    int i;
27780
27781
0
    if (ctxt == NULL)
27782
0
  return (-1);
27783
    /*
27784
    * WARNING: Change the start value if adding to the
27785
    * xmlSchemaValidOption.
27786
    * TODO: Is there an other, more easy to maintain,
27787
    * way?
27788
    */
27789
0
    for (i = 1; i < (int) sizeof(int) * 8; i++) {
27790
0
        if (options & 1<<i)
27791
0
      return (-1);
27792
0
    }
27793
0
    ctxt->options = options;
27794
0
    return (0);
27795
0
}
27796
27797
/**
27798
 * xmlSchemaValidCtxtGetOptions:
27799
 * @ctxt: a schema validation context
27800
 *
27801
 * Get the validation context options.
27802
 *
27803
 * Returns the option combination or -1 on error.
27804
 */
27805
int
27806
xmlSchemaValidCtxtGetOptions(xmlSchemaValidCtxtPtr ctxt)
27807
27808
0
{
27809
0
    if (ctxt == NULL)
27810
0
  return (-1);
27811
0
    else
27812
0
  return (ctxt->options);
27813
0
}
27814
27815
static int
27816
xmlSchemaVDocWalk(xmlSchemaValidCtxtPtr vctxt)
27817
0
{
27818
0
    xmlAttrPtr attr;
27819
0
    int ret = 0;
27820
0
    xmlSchemaNodeInfoPtr ielem = NULL;
27821
0
    xmlNodePtr node, valRoot;
27822
0
    const xmlChar *nsName;
27823
27824
    /* DOC VAL TODO: Move this to the start function. */
27825
0
    if (vctxt->validationRoot != NULL)
27826
0
        valRoot = vctxt->validationRoot;
27827
0
    else
27828
0
  valRoot = xmlDocGetRootElement(vctxt->doc);
27829
0
    if (valRoot == NULL) {
27830
  /* VAL TODO: Error code? */
27831
0
  VERROR(1, NULL, "The document has no document element");
27832
0
  return (1);
27833
0
    }
27834
0
    vctxt->depth = -1;
27835
0
    vctxt->validationRoot = valRoot;
27836
0
    node = valRoot;
27837
0
    while (node != NULL) {
27838
0
  if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
27839
0
      goto next_sibling;
27840
0
  if (node->type == XML_ELEMENT_NODE) {
27841
27842
      /*
27843
      * Init the node-info.
27844
      */
27845
0
      vctxt->depth++;
27846
0
      if (xmlSchemaValidatorPushElem(vctxt) == -1)
27847
0
    goto internal_error;
27848
0
      ielem = vctxt->inode;
27849
0
      ielem->node = node;
27850
0
      ielem->nodeLine = node->line;
27851
0
      ielem->localName = node->name;
27852
0
      if (node->ns != NULL)
27853
0
    ielem->nsName = node->ns->href;
27854
0
      ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY;
27855
      /*
27856
      * Register attributes.
27857
      * DOC VAL TODO: We do not register namespace declaration
27858
      * attributes yet.
27859
      */
27860
0
      vctxt->nbAttrInfos = 0;
27861
0
      if (node->properties != NULL) {
27862
0
    attr = node->properties;
27863
0
    do {
27864
0
                    xmlChar *content;
27865
27866
0
        if (attr->ns != NULL)
27867
0
      nsName = attr->ns->href;
27868
0
        else
27869
0
      nsName = NULL;
27870
0
                    content = xmlNodeListGetString(attr->doc,
27871
0
                                                   attr->children, 1);
27872
0
        ret = xmlSchemaValidatorPushAttribute(vctxt,
27873
0
      (xmlNodePtr) attr,
27874
      /*
27875
      * Note that we give it the line number of the
27876
      * parent element.
27877
      */
27878
0
      ielem->nodeLine,
27879
0
      attr->name, nsName, 0,
27880
0
      content, 1);
27881
0
        if (ret == -1) {
27882
0
      VERROR_INT("xmlSchemaDocWalk",
27883
0
          "calling xmlSchemaValidatorPushAttribute()");
27884
0
                        xmlFree(content);
27885
0
      goto internal_error;
27886
0
        }
27887
0
        attr = attr->next;
27888
0
    } while (attr);
27889
0
      }
27890
      /*
27891
      * Validate the element.
27892
      */
27893
0
      ret = xmlSchemaValidateElem(vctxt);
27894
0
      if (ret != 0) {
27895
0
    if (ret == -1) {
27896
0
        VERROR_INT("xmlSchemaDocWalk",
27897
0
      "calling xmlSchemaValidateElem()");
27898
0
        goto internal_error;
27899
0
    }
27900
    /*
27901
    * Don't stop validation; just skip the content
27902
    * of this element.
27903
    */
27904
0
    goto leave_node;
27905
0
      }
27906
0
      if ((vctxt->skipDepth != -1) &&
27907
0
    (vctxt->depth >= vctxt->skipDepth))
27908
0
    goto leave_node;
27909
0
  } else if ((node->type == XML_TEXT_NODE) ||
27910
0
      (node->type == XML_CDATA_SECTION_NODE)) {
27911
      /*
27912
      * Process character content.
27913
      */
27914
0
      if ((ielem != NULL) && (ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY))
27915
0
    ielem->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
27916
0
      ret = xmlSchemaVPushText(vctxt, node->type, node->content,
27917
0
    -1, XML_SCHEMA_PUSH_TEXT_PERSIST, NULL);
27918
0
      if (ret < 0) {
27919
0
    VERROR_INT("xmlSchemaVDocWalk",
27920
0
        "calling xmlSchemaVPushText()");
27921
0
    goto internal_error;
27922
0
      }
27923
      /*
27924
      * DOC VAL TODO: Should we skip further validation of the
27925
      * element content here?
27926
      */
27927
0
  } else if ((node->type == XML_ENTITY_NODE) ||
27928
0
      (node->type == XML_ENTITY_REF_NODE)) {
27929
      /*
27930
      * DOC VAL TODO: What to do with entities?
27931
      */
27932
0
      VERROR_INT("xmlSchemaVDocWalk",
27933
0
    "there is at least one entity reference in the node-tree "
27934
0
    "currently being validated. Processing of entities with "
27935
0
    "this XML Schema processor is not supported (yet). Please "
27936
0
    "substitute entities before validation.");
27937
0
      goto internal_error;
27938
0
  } else {
27939
0
      goto leave_node;
27940
      /*
27941
      * DOC VAL TODO: XInclude nodes, etc.
27942
      */
27943
0
  }
27944
  /*
27945
  * Walk the doc.
27946
  */
27947
0
  if (node->children != NULL) {
27948
0
      node = node->children;
27949
0
      continue;
27950
0
  }
27951
0
leave_node:
27952
0
  if (node->type == XML_ELEMENT_NODE) {
27953
      /*
27954
      * Leaving the scope of an element.
27955
      */
27956
0
      if (node != vctxt->inode->node) {
27957
0
    VERROR_INT("xmlSchemaVDocWalk",
27958
0
        "element position mismatch");
27959
0
    goto internal_error;
27960
0
      }
27961
0
      ret = xmlSchemaValidatorPopElem(vctxt);
27962
0
      if (ret != 0) {
27963
0
    if (ret < 0) {
27964
0
        VERROR_INT("xmlSchemaVDocWalk",
27965
0
      "calling xmlSchemaValidatorPopElem()");
27966
0
        goto internal_error;
27967
0
    }
27968
0
      }
27969
0
      if (node == valRoot)
27970
0
    goto exit;
27971
0
  }
27972
0
next_sibling:
27973
0
  if (node->next != NULL)
27974
0
      node = node->next;
27975
0
  else {
27976
0
      node = node->parent;
27977
0
      goto leave_node;
27978
0
  }
27979
0
    }
27980
27981
0
exit:
27982
0
    return (ret);
27983
0
internal_error:
27984
0
    return (-1);
27985
0
}
27986
27987
static int
27988
0
xmlSchemaPreRun(xmlSchemaValidCtxtPtr vctxt) {
27989
    /*
27990
    * Some initialization.
27991
    */
27992
0
    vctxt->err = 0;
27993
0
    vctxt->nberrors = 0;
27994
0
    vctxt->depth = -1;
27995
0
    vctxt->skipDepth = -1;
27996
0
    vctxt->hasKeyrefs = 0;
27997
#ifdef ENABLE_IDC_NODE_TABLES_TEST
27998
    vctxt->createIDCNodeTables = 1;
27999
#else
28000
0
    vctxt->createIDCNodeTables = 0;
28001
0
#endif
28002
    /*
28003
    * Create a schema + parser if necessary.
28004
    */
28005
0
    if (vctxt->schema == NULL) {
28006
0
  xmlSchemaParserCtxtPtr pctxt;
28007
28008
0
  vctxt->xsiAssemble = 1;
28009
  /*
28010
  * If not schema was given then we will create a schema
28011
  * dynamically using XSI schema locations.
28012
  *
28013
  * Create the schema parser context.
28014
  */
28015
0
  if ((vctxt->pctxt == NULL) &&
28016
0
     (xmlSchemaCreatePCtxtOnVCtxt(vctxt) == -1))
28017
0
     return (-1);
28018
0
  pctxt = vctxt->pctxt;
28019
0
  pctxt->xsiAssemble = 1;
28020
  /*
28021
  * Create the schema.
28022
  */
28023
0
  vctxt->schema = xmlSchemaNewSchema(pctxt);
28024
0
  if (vctxt->schema == NULL)
28025
0
      return (-1);
28026
  /*
28027
  * Create the schema construction context.
28028
  */
28029
0
  pctxt->constructor = xmlSchemaConstructionCtxtCreate(pctxt->dict);
28030
0
  if (pctxt->constructor == NULL)
28031
0
      return(-1);
28032
0
  pctxt->constructor->mainSchema = vctxt->schema;
28033
  /*
28034
  * Take ownership of the constructor to be able to free it.
28035
  */
28036
0
  pctxt->ownsConstructor = 1;
28037
0
    }
28038
    /*
28039
    * Augment the IDC definitions for the main schema and all imported ones
28040
    * NOTE: main schema if the first in the imported list
28041
    */
28042
0
    xmlHashScan(vctxt->schema->schemasImports, xmlSchemaAugmentImportedIDC,
28043
0
                vctxt);
28044
28045
0
    return(0);
28046
0
}
28047
28048
static void
28049
0
xmlSchemaPostRun(xmlSchemaValidCtxtPtr vctxt) {
28050
0
    if (vctxt->xsiAssemble) {
28051
0
  if (vctxt->schema != NULL) {
28052
0
      xmlSchemaFree(vctxt->schema);
28053
0
      vctxt->schema = NULL;
28054
0
  }
28055
0
    }
28056
0
    xmlSchemaClearValidCtxt(vctxt);
28057
0
}
28058
28059
static int
28060
xmlSchemaVStart(xmlSchemaValidCtxtPtr vctxt)
28061
0
{
28062
0
    int ret = 0;
28063
28064
0
    if (xmlSchemaPreRun(vctxt) < 0)
28065
0
        return(-1);
28066
28067
0
    if (vctxt->doc != NULL) {
28068
  /*
28069
   * Tree validation.
28070
   */
28071
0
  ret = xmlSchemaVDocWalk(vctxt);
28072
0
#ifdef LIBXML_READER_ENABLED
28073
0
    } else if (vctxt->reader != NULL) {
28074
  /*
28075
   * XML Reader validation.
28076
   */
28077
#ifdef XML_SCHEMA_READER_ENABLED
28078
  ret = xmlSchemaVReaderWalk(vctxt);
28079
#endif
28080
0
#endif
28081
0
    } else if ((vctxt->sax != NULL) && (vctxt->parserCtxt != NULL)) {
28082
  /*
28083
   * SAX validation.
28084
   */
28085
0
  ret = xmlParseDocument(vctxt->parserCtxt);
28086
0
    } else {
28087
0
  VERROR_INT("xmlSchemaVStart",
28088
0
      "no instance to validate");
28089
0
  ret = -1;
28090
0
    }
28091
28092
0
    xmlSchemaPostRun(vctxt);
28093
0
    if (ret == 0)
28094
0
  ret = vctxt->err;
28095
0
    return (ret);
28096
0
}
28097
28098
/**
28099
 * xmlSchemaValidateOneElement:
28100
 * @ctxt:  a schema validation context
28101
 * @elem:  an element node
28102
 *
28103
 * Validate a branch of a tree, starting with the given @elem.
28104
 *
28105
 * Returns 0 if the element and its subtree is valid, a positive error
28106
 * code number otherwise and -1 in case of an internal or API error.
28107
 */
28108
int
28109
xmlSchemaValidateOneElement(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr elem)
28110
0
{
28111
0
    if ((ctxt == NULL) || (elem == NULL) || (elem->type != XML_ELEMENT_NODE))
28112
0
  return (-1);
28113
28114
0
    if (ctxt->schema == NULL)
28115
0
  return (-1);
28116
28117
0
    ctxt->doc = elem->doc;
28118
0
    ctxt->node = elem;
28119
0
    ctxt->validationRoot = elem;
28120
0
    return(xmlSchemaVStart(ctxt));
28121
0
}
28122
28123
/**
28124
 * xmlSchemaValidateDoc:
28125
 * @ctxt:  a schema validation context
28126
 * @doc:  a parsed document tree
28127
 *
28128
 * Validate a document tree in memory.
28129
 *
28130
 * Returns 0 if the document is schemas valid, a positive error code
28131
 *     number otherwise and -1 in case of internal or API error.
28132
 */
28133
int
28134
xmlSchemaValidateDoc(xmlSchemaValidCtxtPtr ctxt, xmlDocPtr doc)
28135
0
{
28136
0
    if ((ctxt == NULL) || (doc == NULL))
28137
0
        return (-1);
28138
28139
0
    ctxt->doc = doc;
28140
0
    ctxt->node = xmlDocGetRootElement(doc);
28141
0
    if (ctxt->node == NULL) {
28142
0
        xmlSchemaCustomErr(ACTXT_CAST ctxt,
28143
0
      XML_SCHEMAV_DOCUMENT_ELEMENT_MISSING,
28144
0
      (xmlNodePtr) doc, NULL,
28145
0
      "The document has no document element", NULL, NULL);
28146
0
        return (ctxt->err);
28147
0
    }
28148
0
    ctxt->validationRoot = ctxt->node;
28149
0
    return (xmlSchemaVStart(ctxt));
28150
0
}
28151
28152
28153
/************************************************************************
28154
 *                  *
28155
 *    Function and data for SAX streaming API     *
28156
 *                  *
28157
 ************************************************************************/
28158
typedef struct _xmlSchemaSplitSAXData xmlSchemaSplitSAXData;
28159
typedef xmlSchemaSplitSAXData *xmlSchemaSplitSAXDataPtr;
28160
28161
struct _xmlSchemaSplitSAXData {
28162
    xmlSAXHandlerPtr      user_sax;
28163
    void                 *user_data;
28164
    xmlSchemaValidCtxtPtr ctxt;
28165
    xmlSAXHandlerPtr      schemas_sax;
28166
};
28167
28168
0
#define XML_SAX_PLUG_MAGIC 0xdc43ba21
28169
28170
struct _xmlSchemaSAXPlug {
28171
    unsigned int magic;
28172
28173
    /* the original callbacks information */
28174
    xmlSAXHandlerPtr     *user_sax_ptr;
28175
    xmlSAXHandlerPtr      user_sax;
28176
    void                **user_data_ptr;
28177
    void                 *user_data;
28178
28179
    /* the block plugged back and validation information */
28180
    xmlSAXHandler         schemas_sax;
28181
    xmlSchemaValidCtxtPtr ctxt;
28182
};
28183
28184
/* All those functions just bounces to the user provided SAX handlers */
28185
static void
28186
internalSubsetSplit(void *ctx, const xmlChar *name,
28187
         const xmlChar *ExternalID, const xmlChar *SystemID)
28188
0
{
28189
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28190
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28191
0
        (ctxt->user_sax->internalSubset != NULL))
28192
0
  ctxt->user_sax->internalSubset(ctxt->user_data, name, ExternalID,
28193
0
                                 SystemID);
28194
0
}
28195
28196
static int
28197
isStandaloneSplit(void *ctx)
28198
0
{
28199
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28200
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28201
0
        (ctxt->user_sax->isStandalone != NULL))
28202
0
  return(ctxt->user_sax->isStandalone(ctxt->user_data));
28203
0
    return(0);
28204
0
}
28205
28206
static int
28207
hasInternalSubsetSplit(void *ctx)
28208
0
{
28209
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28210
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28211
0
        (ctxt->user_sax->hasInternalSubset != NULL))
28212
0
  return(ctxt->user_sax->hasInternalSubset(ctxt->user_data));
28213
0
    return(0);
28214
0
}
28215
28216
static int
28217
hasExternalSubsetSplit(void *ctx)
28218
0
{
28219
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28220
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28221
0
        (ctxt->user_sax->hasExternalSubset != NULL))
28222
0
  return(ctxt->user_sax->hasExternalSubset(ctxt->user_data));
28223
0
    return(0);
28224
0
}
28225
28226
static void
28227
externalSubsetSplit(void *ctx, const xmlChar *name,
28228
         const xmlChar *ExternalID, const xmlChar *SystemID)
28229
0
{
28230
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28231
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28232
0
        (ctxt->user_sax->externalSubset != NULL))
28233
0
  ctxt->user_sax->externalSubset(ctxt->user_data, name, ExternalID,
28234
0
                                 SystemID);
28235
0
}
28236
28237
static xmlParserInputPtr
28238
resolveEntitySplit(void *ctx, const xmlChar *publicId, const xmlChar *systemId)
28239
0
{
28240
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28241
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28242
0
        (ctxt->user_sax->resolveEntity != NULL))
28243
0
  return(ctxt->user_sax->resolveEntity(ctxt->user_data, publicId,
28244
0
                                       systemId));
28245
0
    return(NULL);
28246
0
}
28247
28248
static xmlEntityPtr
28249
getEntitySplit(void *ctx, const xmlChar *name)
28250
0
{
28251
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28252
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28253
0
        (ctxt->user_sax->getEntity != NULL))
28254
0
  return(ctxt->user_sax->getEntity(ctxt->user_data, name));
28255
0
    return(NULL);
28256
0
}
28257
28258
static xmlEntityPtr
28259
getParameterEntitySplit(void *ctx, const xmlChar *name)
28260
0
{
28261
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28262
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28263
0
        (ctxt->user_sax->getParameterEntity != NULL))
28264
0
  return(ctxt->user_sax->getParameterEntity(ctxt->user_data, name));
28265
0
    return(NULL);
28266
0
}
28267
28268
28269
static void
28270
entityDeclSplit(void *ctx, const xmlChar *name, int type,
28271
          const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)
28272
0
{
28273
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28274
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28275
0
        (ctxt->user_sax->entityDecl != NULL))
28276
0
  ctxt->user_sax->entityDecl(ctxt->user_data, name, type, publicId,
28277
0
                             systemId, content);
28278
0
}
28279
28280
static void
28281
attributeDeclSplit(void *ctx, const xmlChar * elem,
28282
                   const xmlChar * name, int type, int def,
28283
                   const xmlChar * defaultValue, xmlEnumerationPtr tree)
28284
0
{
28285
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28286
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28287
0
        (ctxt->user_sax->attributeDecl != NULL)) {
28288
0
  ctxt->user_sax->attributeDecl(ctxt->user_data, elem, name, type,
28289
0
                                def, defaultValue, tree);
28290
0
    } else {
28291
0
  xmlFreeEnumeration(tree);
28292
0
    }
28293
0
}
28294
28295
static void
28296
elementDeclSplit(void *ctx, const xmlChar *name, int type,
28297
      xmlElementContentPtr content)
28298
0
{
28299
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28300
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28301
0
        (ctxt->user_sax->elementDecl != NULL))
28302
0
  ctxt->user_sax->elementDecl(ctxt->user_data, name, type, content);
28303
0
}
28304
28305
static void
28306
notationDeclSplit(void *ctx, const xmlChar *name,
28307
       const xmlChar *publicId, const xmlChar *systemId)
28308
0
{
28309
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28310
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28311
0
        (ctxt->user_sax->notationDecl != NULL))
28312
0
  ctxt->user_sax->notationDecl(ctxt->user_data, name, publicId,
28313
0
                               systemId);
28314
0
}
28315
28316
static void
28317
unparsedEntityDeclSplit(void *ctx, const xmlChar *name,
28318
       const xmlChar *publicId, const xmlChar *systemId,
28319
       const xmlChar *notationName)
28320
0
{
28321
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28322
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28323
0
        (ctxt->user_sax->unparsedEntityDecl != NULL))
28324
0
  ctxt->user_sax->unparsedEntityDecl(ctxt->user_data, name, publicId,
28325
0
                                     systemId, notationName);
28326
0
}
28327
28328
static void
28329
setDocumentLocatorSplit(void *ctx, xmlSAXLocatorPtr loc)
28330
0
{
28331
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28332
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28333
0
        (ctxt->user_sax->setDocumentLocator != NULL))
28334
0
  ctxt->user_sax->setDocumentLocator(ctxt->user_data, loc);
28335
0
}
28336
28337
static void
28338
startDocumentSplit(void *ctx)
28339
0
{
28340
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28341
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28342
0
        (ctxt->user_sax->startDocument != NULL))
28343
0
  ctxt->user_sax->startDocument(ctxt->user_data);
28344
0
}
28345
28346
static void
28347
endDocumentSplit(void *ctx)
28348
0
{
28349
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28350
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28351
0
        (ctxt->user_sax->endDocument != NULL))
28352
0
  ctxt->user_sax->endDocument(ctxt->user_data);
28353
0
}
28354
28355
static void
28356
processingInstructionSplit(void *ctx, const xmlChar *target,
28357
                      const xmlChar *data)
28358
0
{
28359
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28360
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28361
0
        (ctxt->user_sax->processingInstruction != NULL))
28362
0
  ctxt->user_sax->processingInstruction(ctxt->user_data, target, data);
28363
0
}
28364
28365
static void
28366
commentSplit(void *ctx, const xmlChar *value)
28367
0
{
28368
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28369
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28370
0
        (ctxt->user_sax->comment != NULL))
28371
0
  ctxt->user_sax->comment(ctxt->user_data, value);
28372
0
}
28373
28374
/*
28375
 * Varargs error callbacks to the user application, harder ...
28376
 */
28377
28378
static void
28379
0
warningSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) {
28380
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28381
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28382
0
        (ctxt->user_sax->warning != NULL)) {
28383
  /* TODO */
28384
0
    }
28385
0
}
28386
static void
28387
0
errorSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) {
28388
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28389
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28390
0
        (ctxt->user_sax->error != NULL)) {
28391
  /* TODO */
28392
0
    }
28393
0
}
28394
static void
28395
0
fatalErrorSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) {
28396
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28397
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28398
0
        (ctxt->user_sax->fatalError != NULL)) {
28399
  /* TODO */
28400
0
    }
28401
0
}
28402
28403
/*
28404
 * Those are function where both the user handler and the schemas handler
28405
 * need to be called.
28406
 */
28407
static void
28408
charactersSplit(void *ctx, const xmlChar *ch, int len)
28409
0
{
28410
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28411
0
    if (ctxt == NULL)
28412
0
        return;
28413
0
    if ((ctxt->user_sax != NULL) && (ctxt->user_sax->characters != NULL))
28414
0
  ctxt->user_sax->characters(ctxt->user_data, ch, len);
28415
0
    if (ctxt->ctxt != NULL)
28416
0
  xmlSchemaSAXHandleText(ctxt->ctxt, ch, len);
28417
0
}
28418
28419
static void
28420
ignorableWhitespaceSplit(void *ctx, const xmlChar *ch, int len)
28421
0
{
28422
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28423
0
    if (ctxt == NULL)
28424
0
        return;
28425
0
    if ((ctxt->user_sax != NULL) &&
28426
0
        (ctxt->user_sax->ignorableWhitespace != NULL))
28427
0
  ctxt->user_sax->ignorableWhitespace(ctxt->user_data, ch, len);
28428
0
    if (ctxt->ctxt != NULL)
28429
0
  xmlSchemaSAXHandleText(ctxt->ctxt, ch, len);
28430
0
}
28431
28432
static void
28433
cdataBlockSplit(void *ctx, const xmlChar *value, int len)
28434
0
{
28435
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28436
0
    if (ctxt == NULL)
28437
0
        return;
28438
0
    if ((ctxt->user_sax != NULL) &&
28439
0
        (ctxt->user_sax->cdataBlock != NULL))
28440
0
  ctxt->user_sax->cdataBlock(ctxt->user_data, value, len);
28441
0
    if (ctxt->ctxt != NULL)
28442
0
  xmlSchemaSAXHandleCDataSection(ctxt->ctxt, value, len);
28443
0
}
28444
28445
static void
28446
referenceSplit(void *ctx, const xmlChar *name)
28447
0
{
28448
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28449
0
    if (ctxt == NULL)
28450
0
        return;
28451
0
    if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28452
0
        (ctxt->user_sax->reference != NULL))
28453
0
  ctxt->user_sax->reference(ctxt->user_data, name);
28454
0
    if (ctxt->ctxt != NULL)
28455
0
        xmlSchemaSAXHandleReference(ctxt->user_data, name);
28456
0
}
28457
28458
static void
28459
startElementNsSplit(void *ctx, const xmlChar * localname,
28460
        const xmlChar * prefix, const xmlChar * URI,
28461
        int nb_namespaces, const xmlChar ** namespaces,
28462
        int nb_attributes, int nb_defaulted,
28463
0
        const xmlChar ** attributes) {
28464
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28465
0
    if (ctxt == NULL)
28466
0
        return;
28467
0
    if ((ctxt->user_sax != NULL) &&
28468
0
        (ctxt->user_sax->startElementNs != NULL))
28469
0
  ctxt->user_sax->startElementNs(ctxt->user_data, localname, prefix,
28470
0
                                 URI, nb_namespaces, namespaces,
28471
0
               nb_attributes, nb_defaulted,
28472
0
               attributes);
28473
0
    if (ctxt->ctxt != NULL)
28474
0
  xmlSchemaSAXHandleStartElementNs(ctxt->ctxt, localname, prefix,
28475
0
                                   URI, nb_namespaces, namespaces,
28476
0
           nb_attributes, nb_defaulted,
28477
0
           attributes);
28478
0
}
28479
28480
static void
28481
endElementNsSplit(void *ctx, const xmlChar * localname,
28482
0
        const xmlChar * prefix, const xmlChar * URI) {
28483
0
    xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28484
0
    if (ctxt == NULL)
28485
0
        return;
28486
0
    if ((ctxt->user_sax != NULL) &&
28487
0
        (ctxt->user_sax->endElementNs != NULL))
28488
0
  ctxt->user_sax->endElementNs(ctxt->user_data, localname, prefix, URI);
28489
0
    if (ctxt->ctxt != NULL)
28490
0
  xmlSchemaSAXHandleEndElementNs(ctxt->ctxt, localname, prefix, URI);
28491
0
}
28492
28493
/**
28494
 * xmlSchemaSAXPlug:
28495
 * @ctxt:  a schema validation context
28496
 * @sax:  a pointer to the original xmlSAXHandlerPtr
28497
 * @user_data:  a pointer to the original SAX user data pointer
28498
 *
28499
 * Plug a SAX based validation layer in a SAX parsing event flow.
28500
 * The original @saxptr and @dataptr data are replaced by new pointers
28501
 * but the calls to the original will be maintained.
28502
 *
28503
 * Returns a pointer to a data structure needed to unplug the validation layer
28504
 *         or NULL in case of errors.
28505
 */
28506
xmlSchemaSAXPlugPtr
28507
xmlSchemaSAXPlug(xmlSchemaValidCtxtPtr ctxt,
28508
     xmlSAXHandlerPtr *sax, void **user_data)
28509
0
{
28510
0
    xmlSchemaSAXPlugPtr ret;
28511
0
    xmlSAXHandlerPtr old_sax;
28512
28513
0
    if ((ctxt == NULL) || (sax == NULL) || (user_data == NULL))
28514
0
        return(NULL);
28515
28516
    /*
28517
     * We only allow to plug into SAX2 event streams
28518
     */
28519
0
    old_sax = *sax;
28520
0
    if ((old_sax != NULL) && (old_sax->initialized != XML_SAX2_MAGIC))
28521
0
        return(NULL);
28522
0
    if ((old_sax != NULL) &&
28523
0
        (old_sax->startElementNs == NULL) && (old_sax->endElementNs == NULL) &&
28524
0
        ((old_sax->startElement != NULL) || (old_sax->endElement != NULL)))
28525
0
        return(NULL);
28526
28527
    /*
28528
     * everything seems right allocate the local data needed for that layer
28529
     */
28530
0
    ret = (xmlSchemaSAXPlugPtr) xmlMalloc(sizeof(xmlSchemaSAXPlugStruct));
28531
0
    if (ret == NULL) {
28532
0
        return(NULL);
28533
0
    }
28534
0
    memset(ret, 0, sizeof(xmlSchemaSAXPlugStruct));
28535
0
    ret->magic = XML_SAX_PLUG_MAGIC;
28536
0
    ret->schemas_sax.initialized = XML_SAX2_MAGIC;
28537
0
    ret->ctxt = ctxt;
28538
0
    ret->user_sax_ptr = sax;
28539
0
    ret->user_sax = old_sax;
28540
0
    if (old_sax == NULL) {
28541
        /*
28542
   * go direct, no need for the split block and functions.
28543
   */
28544
0
  ret->schemas_sax.startElementNs = xmlSchemaSAXHandleStartElementNs;
28545
0
  ret->schemas_sax.endElementNs = xmlSchemaSAXHandleEndElementNs;
28546
  /*
28547
   * Note that we use the same text-function for both, to prevent
28548
   * the parser from testing for ignorable whitespace.
28549
   */
28550
0
  ret->schemas_sax.ignorableWhitespace = xmlSchemaSAXHandleText;
28551
0
  ret->schemas_sax.characters = xmlSchemaSAXHandleText;
28552
28553
0
  ret->schemas_sax.cdataBlock = xmlSchemaSAXHandleCDataSection;
28554
0
  ret->schemas_sax.reference = xmlSchemaSAXHandleReference;
28555
28556
0
  ret->user_data = ctxt;
28557
0
  *user_data = ctxt;
28558
0
    } else {
28559
       /*
28560
        * for each callback unused by Schemas initialize it to the Split
28561
  * routine only if non NULL in the user block, this can speed up
28562
  * things at the SAX level.
28563
  */
28564
0
        if (old_sax->internalSubset != NULL)
28565
0
            ret->schemas_sax.internalSubset = internalSubsetSplit;
28566
0
        if (old_sax->isStandalone != NULL)
28567
0
            ret->schemas_sax.isStandalone = isStandaloneSplit;
28568
0
        if (old_sax->hasInternalSubset != NULL)
28569
0
            ret->schemas_sax.hasInternalSubset = hasInternalSubsetSplit;
28570
0
        if (old_sax->hasExternalSubset != NULL)
28571
0
            ret->schemas_sax.hasExternalSubset = hasExternalSubsetSplit;
28572
0
        if (old_sax->resolveEntity != NULL)
28573
0
            ret->schemas_sax.resolveEntity = resolveEntitySplit;
28574
0
        if (old_sax->getEntity != NULL)
28575
0
            ret->schemas_sax.getEntity = getEntitySplit;
28576
0
        if (old_sax->entityDecl != NULL)
28577
0
            ret->schemas_sax.entityDecl = entityDeclSplit;
28578
0
        if (old_sax->notationDecl != NULL)
28579
0
            ret->schemas_sax.notationDecl = notationDeclSplit;
28580
0
        if (old_sax->attributeDecl != NULL)
28581
0
            ret->schemas_sax.attributeDecl = attributeDeclSplit;
28582
0
        if (old_sax->elementDecl != NULL)
28583
0
            ret->schemas_sax.elementDecl = elementDeclSplit;
28584
0
        if (old_sax->unparsedEntityDecl != NULL)
28585
0
            ret->schemas_sax.unparsedEntityDecl = unparsedEntityDeclSplit;
28586
0
        if (old_sax->setDocumentLocator != NULL)
28587
0
            ret->schemas_sax.setDocumentLocator = setDocumentLocatorSplit;
28588
0
        if (old_sax->startDocument != NULL)
28589
0
            ret->schemas_sax.startDocument = startDocumentSplit;
28590
0
        if (old_sax->endDocument != NULL)
28591
0
            ret->schemas_sax.endDocument = endDocumentSplit;
28592
0
        if (old_sax->processingInstruction != NULL)
28593
0
            ret->schemas_sax.processingInstruction = processingInstructionSplit;
28594
0
        if (old_sax->comment != NULL)
28595
0
            ret->schemas_sax.comment = commentSplit;
28596
0
        if (old_sax->warning != NULL)
28597
0
            ret->schemas_sax.warning = warningSplit;
28598
0
        if (old_sax->error != NULL)
28599
0
            ret->schemas_sax.error = errorSplit;
28600
0
        if (old_sax->fatalError != NULL)
28601
0
            ret->schemas_sax.fatalError = fatalErrorSplit;
28602
0
        if (old_sax->getParameterEntity != NULL)
28603
0
            ret->schemas_sax.getParameterEntity = getParameterEntitySplit;
28604
0
        if (old_sax->externalSubset != NULL)
28605
0
            ret->schemas_sax.externalSubset = externalSubsetSplit;
28606
28607
  /*
28608
   * the 6 schemas callback have to go to the splitter functions
28609
   * Note that we use the same text-function for ignorableWhitespace
28610
   * if possible, to prevent the parser from testing for ignorable
28611
   * whitespace.
28612
   */
28613
0
        ret->schemas_sax.characters = charactersSplit;
28614
0
  if ((old_sax->ignorableWhitespace != NULL) &&
28615
0
      (old_sax->ignorableWhitespace != old_sax->characters))
28616
0
      ret->schemas_sax.ignorableWhitespace = ignorableWhitespaceSplit;
28617
0
  else
28618
0
      ret->schemas_sax.ignorableWhitespace = charactersSplit;
28619
0
        ret->schemas_sax.cdataBlock = cdataBlockSplit;
28620
0
        ret->schemas_sax.reference = referenceSplit;
28621
0
        ret->schemas_sax.startElementNs = startElementNsSplit;
28622
0
        ret->schemas_sax.endElementNs = endElementNsSplit;
28623
28624
0
  ret->user_data_ptr = user_data;
28625
0
  ret->user_data = *user_data;
28626
0
  *user_data = ret;
28627
0
    }
28628
28629
    /*
28630
     * plug the pointers back.
28631
     */
28632
0
    *sax = &(ret->schemas_sax);
28633
0
    ctxt->sax = *sax;
28634
0
    ctxt->flags |= XML_SCHEMA_VALID_CTXT_FLAG_STREAM;
28635
0
    xmlSchemaPreRun(ctxt);
28636
0
    return(ret);
28637
0
}
28638
28639
/**
28640
 * xmlSchemaSAXUnplug:
28641
 * @plug:  a data structure returned by xmlSchemaSAXPlug
28642
 *
28643
 * Unplug a SAX based validation layer in a SAX parsing event flow.
28644
 * The original pointers used in the call are restored.
28645
 *
28646
 * Returns 0 in case of success and -1 in case of failure.
28647
 */
28648
int
28649
xmlSchemaSAXUnplug(xmlSchemaSAXPlugPtr plug)
28650
0
{
28651
0
    xmlSAXHandlerPtr *sax;
28652
0
    void **user_data;
28653
28654
0
    if ((plug == NULL) || (plug->magic != XML_SAX_PLUG_MAGIC))
28655
0
        return(-1);
28656
0
    plug->magic = 0;
28657
28658
0
    xmlSchemaPostRun(plug->ctxt);
28659
    /* restore the data */
28660
0
    sax = plug->user_sax_ptr;
28661
0
    *sax = plug->user_sax;
28662
0
    if (plug->user_sax != NULL) {
28663
0
  user_data = plug->user_data_ptr;
28664
0
  *user_data = plug->user_data;
28665
0
    }
28666
28667
    /* free and return */
28668
0
    xmlFree(plug);
28669
0
    return(0);
28670
0
}
28671
28672
/**
28673
 * xmlSchemaValidateSetLocator:
28674
 * @vctxt: a schema validation context
28675
 * @f: the locator function pointer
28676
 * @ctxt: the locator context
28677
 *
28678
 * Allows to set a locator function to the validation context,
28679
 * which will be used to provide file and line information since
28680
 * those are not provided as part of the SAX validation flow
28681
 * Setting @f to NULL disable the locator.
28682
 */
28683
28684
void
28685
xmlSchemaValidateSetLocator(xmlSchemaValidCtxtPtr vctxt,
28686
                            xmlSchemaValidityLocatorFunc f,
28687
          void *ctxt)
28688
0
{
28689
0
    if (vctxt == NULL) return;
28690
0
    vctxt->locFunc = f;
28691
0
    vctxt->locCtxt = ctxt;
28692
0
}
28693
28694
/**
28695
 * xmlSchemaValidateStreamLocator:
28696
 * @ctx: the xmlTextReaderPtr used
28697
 * @file: returned file information
28698
 * @line: returned line information
28699
 *
28700
 * Internal locator function for the readers
28701
 *
28702
 * Returns 0 in case the Schema validation could be (de)activated and
28703
 *         -1 in case of error.
28704
 */
28705
static int
28706
xmlSchemaValidateStreamLocator(void *ctx, const char **file,
28707
0
                               unsigned long *line) {
28708
0
    xmlParserCtxtPtr ctxt;
28709
28710
0
    if ((ctx == NULL) || ((file == NULL) && (line == NULL)))
28711
0
        return(-1);
28712
28713
0
    if (file != NULL)
28714
0
        *file = NULL;
28715
0
    if (line != NULL)
28716
0
        *line = 0;
28717
28718
0
    ctxt = (xmlParserCtxtPtr) ctx;
28719
0
    if (ctxt->input != NULL) {
28720
0
       if (file != NULL)
28721
0
           *file = ctxt->input->filename;
28722
0
       if (line != NULL)
28723
0
           *line = ctxt->input->line;
28724
0
       return(0);
28725
0
    }
28726
0
    return(-1);
28727
0
}
28728
28729
/**
28730
 * xmlSchemaValidateStreamInternal:
28731
 * @ctxt:  a schema validation context
28732
 * @pctxt:  a parser context
28733
 *
28734
 * Returns 0 if the document is schemas valid, a positive error code
28735
 *     number otherwise and -1 in case of internal or API error.
28736
 */
28737
static int
28738
xmlSchemaValidateStreamInternal(xmlSchemaValidCtxtPtr ctxt,
28739
0
                                 xmlParserCtxtPtr pctxt) {
28740
0
    xmlSchemaSAXPlugPtr plug = NULL;
28741
0
    int ret;
28742
28743
0
    pctxt->linenumbers = 1;
28744
0
    xmlSchemaValidateSetLocator(ctxt, xmlSchemaValidateStreamLocator, pctxt);
28745
28746
0
    ctxt->parserCtxt = pctxt;
28747
0
    ctxt->input = pctxt->input->buf;
28748
28749
    /*
28750
     * Plug the validation and launch the parsing
28751
     */
28752
0
    plug = xmlSchemaSAXPlug(ctxt, &(pctxt->sax), &(pctxt->userData));
28753
0
    if (plug == NULL) {
28754
0
        ret = -1;
28755
0
  goto done;
28756
0
    }
28757
0
    ctxt->input = pctxt->input->buf;
28758
0
    ctxt->sax = pctxt->sax;
28759
0
    ctxt->flags |= XML_SCHEMA_VALID_CTXT_FLAG_STREAM;
28760
0
    ret = xmlSchemaVStart(ctxt);
28761
28762
0
    if ((ret == 0) && (! ctxt->parserCtxt->wellFormed)) {
28763
0
  ret = ctxt->parserCtxt->errNo;
28764
0
  if (ret == 0)
28765
0
      ret = 1;
28766
0
    }
28767
28768
0
done:
28769
0
    ctxt->parserCtxt = NULL;
28770
0
    ctxt->sax = NULL;
28771
0
    ctxt->input = NULL;
28772
0
    if (plug != NULL) {
28773
0
        xmlSchemaSAXUnplug(plug);
28774
0
    }
28775
0
    return (ret);
28776
0
}
28777
28778
/**
28779
 * xmlSchemaValidateStream:
28780
 * @ctxt:  a schema validation context
28781
 * @input:  the input to use for reading the data
28782
 * @enc:  an optional encoding information
28783
 * @sax:  a SAX handler for the resulting events
28784
 * @user_data:  the context to provide to the SAX handler.
28785
 *
28786
 * Validate an input based on a flow of SAX event from the parser
28787
 * and forward the events to the @sax handler with the provided @user_data
28788
 * the user provided @sax handler must be a SAX2 one.
28789
 *
28790
 * Returns 0 if the document is schemas valid, a positive error code
28791
 *     number otherwise and -1 in case of internal or API error.
28792
 */
28793
int
28794
xmlSchemaValidateStream(xmlSchemaValidCtxtPtr ctxt,
28795
                        xmlParserInputBufferPtr input, xmlCharEncoding enc,
28796
                        const xmlSAXHandler *sax, void *user_data)
28797
0
{
28798
0
    xmlParserCtxtPtr pctxt = NULL;
28799
0
    xmlParserInputPtr inputStream = NULL;
28800
0
    int ret;
28801
28802
0
    if ((ctxt == NULL) || (input == NULL))
28803
0
        return (-1);
28804
28805
    /*
28806
     * prepare the parser
28807
     */
28808
0
    if (sax != NULL) {
28809
0
        pctxt = xmlNewSAXParserCtxt(sax, user_data);
28810
0
        if (pctxt == NULL)
28811
0
            return (-1);
28812
0
    } else {
28813
0
        pctxt = xmlNewParserCtxt();
28814
0
        if (pctxt == NULL)
28815
0
            return (-1);
28816
        /* We really want pctxt->sax to be NULL here. */
28817
0
        xmlFree(pctxt->sax);
28818
0
        pctxt->sax = NULL;
28819
0
    }
28820
#if 0
28821
    if (options)
28822
        xmlCtxtUseOptions(pctxt, options);
28823
#endif
28824
28825
0
    inputStream = xmlNewIOInputStream(pctxt, input, enc);;
28826
0
    if (inputStream == NULL) {
28827
0
        ret = -1;
28828
0
  goto done;
28829
0
    }
28830
0
    if (xmlCtxtPushInput(pctxt, inputStream) < 0) {
28831
0
        xmlFreeInputStream(inputStream);
28832
0
        ret = -1;
28833
0
        goto done;
28834
0
    }
28835
28836
0
    ctxt->enc = enc;
28837
28838
0
    ret = xmlSchemaValidateStreamInternal(ctxt, pctxt);
28839
28840
0
done:
28841
    /* cleanup */
28842
0
    if (pctxt != NULL) {
28843
0
  xmlFreeParserCtxt(pctxt);
28844
0
    }
28845
0
    return (ret);
28846
0
}
28847
28848
/**
28849
 * xmlSchemaValidateFile:
28850
 * @ctxt: a schema validation context
28851
 * @filename: the URI of the instance
28852
 * @options: a future set of options, currently unused
28853
 *
28854
 * Do a schemas validation of the given resource, it will use the
28855
 * SAX streamable validation internally.
28856
 *
28857
 * Returns 0 if the document is valid, a positive error code
28858
 *     number otherwise and -1 in case of an internal or API error.
28859
 */
28860
int
28861
xmlSchemaValidateFile(xmlSchemaValidCtxtPtr ctxt,
28862
                      const char * filename,
28863
          int options ATTRIBUTE_UNUSED)
28864
0
{
28865
0
    int ret;
28866
0
    xmlParserCtxtPtr pctxt = NULL;
28867
28868
0
    if ((ctxt == NULL) || (filename == NULL))
28869
0
        return (-1);
28870
28871
0
    pctxt = xmlCreateURLParserCtxt(filename, 0);
28872
0
    if (pctxt == NULL)
28873
0
  return (-1);
28874
    /* We really want pctxt->sax to be NULL here. */
28875
0
    xmlFree(pctxt->sax);
28876
0
    pctxt->sax = NULL;
28877
0
    ret = xmlSchemaValidateStreamInternal(ctxt, pctxt);
28878
0
    xmlFreeParserCtxt(pctxt);
28879
0
    return (ret);
28880
0
}
28881
28882
/**
28883
 * xmlSchemaValidCtxtGetParserCtxt:
28884
 * @ctxt: a schema validation context
28885
 *
28886
 * allow access to the parser context of the schema validation context
28887
 *
28888
 * Returns the parser context of the schema validation context or NULL
28889
 *         in case of error.
28890
 */
28891
xmlParserCtxtPtr
28892
xmlSchemaValidCtxtGetParserCtxt(xmlSchemaValidCtxtPtr ctxt)
28893
0
{
28894
0
    if (ctxt == NULL)
28895
0
        return(NULL);
28896
0
    return (ctxt->parserCtxt);
28897
0
}
28898
28899
#endif /* LIBXML_SCHEMAS_ENABLED */